├── .gitignore ├── .idea ├── caches │ └── build_file_checksums.ser ├── codeStyles │ └── Project.xml ├── dictionaries │ └── static.xml ├── gradle.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── README.md ├── README.md.bak ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── aiceking │ │ └── view_load_retry │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── aiceking │ │ │ └── view_load_retry │ │ │ ├── MainActivity.java │ │ │ ├── activity │ │ │ ├── LoadFragmentActivity.java │ │ │ └── NormalActivity.java │ │ │ ├── application │ │ │ └── MyApplication.java │ │ │ ├── fragment │ │ │ ├── TestFragment.java │ │ │ └── adapter │ │ │ │ └── TestAdapter.java │ │ │ ├── loadretryadapter │ │ │ ├── foractivity │ │ │ │ ├── LoadAdapterForActivity.java │ │ │ │ └── NetErrorAdapterForActivity.java │ │ │ ├── forfragment │ │ │ │ ├── LoadAdapterForFragment.java │ │ │ │ └── NetErrorAdapterForFragment.java │ │ │ ├── forimageview │ │ │ │ ├── LoadAdapterForImageView.java │ │ │ │ └── NetErrorAdapterForImageView.java │ │ │ └── fortablayout │ │ │ │ ├── LoadAdapterForTabLayout.java │ │ │ │ └── NetErrorAdapterForTabLayout.java │ │ │ └── util │ │ │ └── ToolBarUtil.java │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ └── ic_launcher_background.xml │ │ ├── layout │ │ ├── activity_load_fragment.xml │ │ ├── activity_main.xml │ │ ├── activity_normal.xml │ │ ├── fragment_test.xml │ │ ├── load_activity.xml │ │ ├── load_fragment.xml │ │ ├── load_imageview.xml │ │ ├── load_tablayout.xml │ │ ├── recycle_test.xml │ │ ├── retry_activity.xml │ │ ├── retry_fragment.xml │ │ ├── retry_imageview.xml │ │ └── retry_tablayout.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── back.png │ │ ├── ic_launcher.png │ │ ├── ic_launcher_round.png │ │ ├── logo.jpg │ │ └── timeout.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── aiceking │ └── view_load_retry │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── img ├── fixed.gif └── normal.gif ├── settings.gradle └── viewloadretrylibrary ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src ├── androidTest └── java │ └── com │ └── aiceking │ └── viewloadretrylibrary │ └── ExampleInstrumentedTest.java ├── main ├── AndroidManifest.xml ├── java │ └── com │ │ └── aiceking │ │ └── viewloadretrylibrary │ │ ├── adapter │ │ ├── BaseLoadRetryAdapter.java │ │ └── loadRtryAdapterInterface.java │ │ ├── coverview │ │ └── CoverLayout.java │ │ ├── listener │ │ └── LoadRetryListener.java │ │ ├── manager │ │ └── LoadRetryManager.java │ │ └── viewmodel │ │ └── ContentViewModel.java └── res │ └── values │ └── strings.xml └── test └── java └── com └── aiceking └── viewloadretrylibrary └── ExampleUnitTest.java /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/libraries 5 | /.idea/modules.xml 6 | /.idea/workspace.xml 7 | .DS_Store 8 | /build 9 | /captures 10 | .externalNativeBuild 11 | -------------------------------------------------------------------------------- /.idea/caches/build_file_checksums.ser: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aiceking/View-Load-ReTry/4a6ea70a4e2e0095ddf71c9dc15aecb94d6b6137/.idea/caches/build_file_checksums.ser -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15 | 16 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /.idea/dictionaries/static.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 19 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # View-Load-ReTry 2 | 3 | [![](https://jitpack.io/v/NoEndToLF/View-Load-ReTry.svg)](https://jitpack.io/#NoEndToLF/View-Load-ReTry) 4 | 5 | **View-Load-ReTry**:这个加载框架有点不一样,针对View进行加载,加载页面还保持了原View的属性,侧重点在灵活,哪里需要加载哪里 6 | 7 | - **原理** :找到需要加载的View,放入FrameLayout(包含自定义的各种情况的加载反馈View),再把FrameLayout放回需要加载View的Parent中 ,然后根据需求调用显示加载或者异常View。 8 | - **功能** :只要当前需要加载View有Parent就可以实现加载反馈(仅不支持复用型的View场景),同一页面支持N个View的加载,彼此互不影响。 9 | - **封装** :全局配置封装,与业务解耦,一个入口控制全部的加载反馈页面。 10 | 11 | ------------------- 12 | # 示例,Demo只添加了一种Error反馈页面做演示,使用时可按需自定义多种Error反馈页面(Gif中的View残留现象是录制时丢帧问题,嘿嘿) 13 | | 常规使用 |Activity+Fragment多View加载 | 14 | | :--------:| :--------:| 15 | |![normal](https://github.com/NoEndToLF/View-Load-ReTry/blob/master/img/normal.gif)| ![fix](https://raw.githubusercontent.com/NoEndToLF/View-Load-ReTry/master/img/fixed.gif)| 16 |
17 | 18 | # 使用    19 | * [初步配置](#初步配置) 20 | * [引入](#引入) 21 | * [自定义](#自定义加载状态页面-Adapter继承-BaseLoadRetryAdapter下面各方法都是按需被调用取决于你主动设置的显示哪个Adapter) 22 | * [初始化](#示例代码Demo中normal用法建议在-Application的-onCreate中进行初始化有多少个Adapter就添加多少个这里统一了入口是方便管理) 23 | * [使用](#最常规用法针对一个View针对多个View和针对一个View用法一致流程都是针对某个View的) 24 | * [1、注册](#1注册一般在-oncreate中调用) 25 | * [2、开始加载](#2开始加载) 26 | * [3、加载结果回调](#3加载结果回调在你的请求成功和失败的回调中加入加载结果回调) 27 | * [4、解除绑定](#4解除绑定) 28 | * [为何要造这个看起来重复的轮子](#为何要造这个看起来重复的轮子) 29 | * [反馈与建议](#反馈与建议) 30 | 31 | # 初步配置 32 | ## 引入 33 | Step 1. Add it in your root build.gradle at the end of repositories: 34 | 35 | allprojects { 36 | repositories { 37 | ... 38 | maven { url 'https://jitpack.io' } 39 | } 40 | } 41 | Step 2. Add the dependency 42 | 43 | dependencies { 44 | implementation 'com.github.NoEndToLF:View-Load-ReTry:2.0.2' 45 | } 46 | ## 自定义加载状态页面 Adapter,继承 BaseLoadRetryAdapter,下面各方法都是按需被调用,取决于你主动设置的显示哪个Adapter。 47 | | 方法 |参数 | 作用 | 48 | | :-------- | :--------| :--: | 49 | | onLoadStart| View | 显示这个加载状态页面前开始前调用,用于你自定义页面中控件的初始化,此View为当前显示的加载页面View,以下方法中的View都是。 | 50 | | getCoverViewLayoutId | return R.layout | 加载页面的布局Layout | 51 | | onFalied| View,Ogject | 加载失败的回调(会在你主动调用错误页面对应的那个Adapter里调用),Object可以是任意的对象,方便你显示加载错误的原因| 52 | | onSuccess| View | 加载成功的回调(会在你设置的Load状态那个Adapter里调用),这里可以做一些加载动画的停止操作,另需要手动让View.Gone,暴露在这里是方便各位添加加载页面消失的动画| 53 | 54 | 自定义Adapter示例(Demo中normal用法) 55 | ``` java 56 | public class LoadAdapterForActivity extends BaseLoadRetryAdapter{ 57 | @Override 58 | public void onLoadStart(View view) { 59 | ((TextView)view.findViewById(R.id.tv_text)).setText("加载中 ..."); 60 | } 61 | @Override 62 | public void onFalied(View view, Object object) { 63 | } 64 | /**这里在加载完成的时候做了一个淡出动画*/ 65 | @Override 66 | public void onSuccess(View view) { 67 | AlphaAnimation alphaAnimation = new AlphaAnimation(1,0); 68 | alphaAnimation.setDuration(500); 69 | view.startAnimation(alphaAnimation); 70 | view.setVisibility(View.GONE); 71 | } 72 | 73 | @Override 74 | public int getCoverViewLayoutId() { 75 | return R.layout.load_activity; 76 | } 77 | } 78 | ``` 79 | ``` java 80 | /**默认给加载失败页面添加了点击事件,回调到retry方法,开始重试,重试时显示加载中Adapter对应的页面*/ 81 | public class NetErrorAdapterForActivity extends BaseLoadRetryAdapter{ 82 | @Override 83 | public void onLoadStart(View view) { 84 | ((TextView)view.findViewById(R.id.tv_retry)).setText("点击重新加载"); 85 | } 86 | 87 | @Override 88 | public void onFalied(View view, Object object) { 89 | ((ImageView) view.findViewById(R.id.iv_head)).setImageResource(R.mipmap.timeout); 90 | ((TextView)view.findViewById(R.id.tv_text)).setText((String)object); 91 | ((TextView)view.findViewById(R.id.tv_retry)).setVisibility(View.VISIBLE); 92 | } 93 | 94 | @Override 95 | public void onSuccess(View view) { 96 | 97 | } 98 | 99 | @Override 100 | public int getCoverViewLayoutId() { 101 | return R.layout.retry_activity; 102 | } 103 | } 104 | ``` 105 | ## 示例代码(Demo中normal用法):建议在 Application的 onCreate中进行初始化,有多少个Adapter就添加多少个,这里统一了入口是方便管理。 106 | ``` java 107 | LoadRetryManager.getInstance().addAdapter(new LoadAdapterForActivity()); 108 | LoadRetryManager.getInstance().addAdapter(new NetErrorAdapterForActivity());....... 109 | ``` 110 | # 最常规用法,针对一个View(针对多个View和针对一个View用法一致,流程都是针对某个View的) 111 | 112 | | 方法 |参数 | 作用 | 113 | | :-------- | :--------| :--| 114 | | register| View,LoadRetryRefreshListener | 注册 | 115 | | startLoad| View,Class | 开始加载,加载中类Adapter.Calss | 116 | | unRegister| View | 解除绑定| 117 | | unRegister| List | 解除多个View的绑定| 118 | | onSuccess | View | 加载成功,会调用View对应加载中Adapter的onSuccess方法| 119 | | onFailed   |View,Class,Object| 加载失败时显示加载失败类Adapter.Class对应的页面,并调用该Adapter的onFalied()方法,Object为加载失败原因| 120 | 121 | 122 | ### 1、注册,一般在 onCreate中调用 123 | ``` java 124 | LoadRetryManager.getInstance().register(view, new LoadRetryListener() { 125 | @Override 126 | public void load() { 127 | //执行你的网络请求 128 | //dosomething(); 129 | } 130 | 131 | @Override 132 | public void reTry() { 133 | //执行你的重试请求 134 | //dosomethingRetry(); 135 | } 136 | }); 137 | ``` 138 | ### 2、开始加载 139 | ``` java 140 | LoadRetryManager.getInstance().load(view, LoadAdapterForActivity.class); 141 | ``` 142 | ### 3、加载结果回调,在你的请求成功和失败的回调中加入加载结果回调 143 | ``` java 144 | @Override 145 | public void onSuccess(Integer value) { 146 | //加载成功你要做的事..... 147 | 148 | //加载结果回调 149 | LoadRetryManager.getInstance().onSuccess(view); 150 | } 151 | 152 | @Override 153 | public void onFailed(Throwable e) { 154 | //加载失败你要做的事..... 155 | 156 | //加载结果回调 157 | LoadRetryManager.getInstance().onFailed(view, NetErrorAdapterForActivity.class, "请检查网络连接"); 158 | 159 | } 160 | ``` 161 | ### 4、解除绑定 162 | ``` java 163 | //在Activity中 164 | Override 165 | protected void onDestroy() { 166 | super.onDestroy(); 167 | LoadRetryManager.getInstance().unRegister(view); 168 | 169 | //加载多个View时建议在BaseActivity中封装方法,维护一个List,每注册一个加载View就Add一次,解绑时方便操作 170 | LoadRetryManager.getInstance().unRegister(list); 171 | } 172 | ``` 173 | ``` java 174 | //在Fragment中 175 | @Override 176 | public void onDestroyView() { 177 | super.onDestroyView(); 178 | LoadRetryManager.getInstance().unRegister(view); 179 | 180 | //加载多个View时建议在BaseFragment中封装方法,维护一个List,每注册一个加载View就Add一次,解绑时方便操作 181 | LoadRetryManager.getInstance().unRegister(list); 182 | } 183 | ``` 184 | # 为何要造这个看起来重复的轮子 185 | 目前好多开源的加载反馈框架大多是针对Activity和Fragment的,原理都是从根上替换加载布局,但是有个缺点,反馈布局的作用域太大了,不够灵活,现在闲的蛋疼造这个轮子也是为了灵活性,比如说Sample中的同一个页面要加载3块内容的时候,这个轮子的优势就显示出来了,而且原View具有的基本特性加载反馈页面依然包含。 186 | 187 | # 反馈与建议 188 | - 邮箱: 189 | 190 | # License 191 | ``` 192 | Copyright (c) [2018] [static] 193 | 194 | Permission is hereby granted, free of charge, to any person obtaining a copy 195 | of this software and associated documentation files (the "Software"), to deal 196 | in the Software without restriction, including without limitation the rights 197 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 198 | copies of the Software, and to permit persons to whom the Software is 199 | furnished to do so, subject to the following conditions: 200 | 201 | The above copyright notice and this permission notice shall be included in all 202 | copies or substantial portions of the Software. 203 | 204 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 205 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 206 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 207 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 208 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 209 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 210 | SOFTWARE. 211 | ``` 212 | --------- 213 | -------------------------------------------------------------------------------- /README.md.bak: -------------------------------------------------------------------------------- 1 | # View-Load-ReTry 2 | 3 | [![](https://jitpack.io/v/NoEndToLF/View-Load-ReTry.svg)](https://jitpack.io/#NoEndToLF/View-Load-ReTry) 4 | 5 | **View-Load-ReTry**:这个加载框架有点不一样,针对View进行加载,加载页面还保持了原View的属性,侧重点在灵活,哪里需要加载哪里 6 | 7 | - **原理** :找到需要加载的View,放入FrameLayout(包含自定义的各种情况的加载反馈View),再把FrameLayout放回需要加载View的Parent中 ,然后根据需求调用显示加载或者异常View。 8 | - **功能** :只要当前需要加载View有Parent就可以实现加载反馈(仅不支持复用型的View场景),同一页面支持N个View的加载,彼此互不影响。 9 | - **封装** :全局配置封装,与业务解耦,一个入口控制全部的加载反馈页面。 10 | 11 | ------------------- 12 | # 示例,Demo只添加了一种Error反馈页面做演示,使用时可按需自定义多种Error反馈页面(Gif中的View残留现象是录制时丢帧问题,嘿嘿) 13 | | 常规使用 |Activity+Fragment多View加载 | 14 | | :--------:| :--------:| 15 | |![normal](https://github.com/NoEndToLF/View-Load-ReTry/blob/master/img/normal.gif)| ![fix](https://raw.githubusercontent.com/NoEndToLF/View-Load-ReTry/master/img/fixed.gif)| 16 |
17 | 18 | # 使用    19 | * [初步配置](#初步配置) 20 | * [引入](#引入) 21 | * [自定义](#自定义加载状态页面-Adapter继承-BaseLoadRetryAdapter下面各方法都是按需被调用取决于你主动设置的显示哪个Adapter) 22 | * [初始化](#示例代码Demo中normal用法建议在-Application的-onCreate中进行初始化有多少个Adapter就添加多少个这里统一了入口是方便管理) 23 | * [使用](#最常规用法针对一个View针对多个View和针对一个View用法一致流程都是针对某个View的) 24 | * [1、注册](#1注册一般在-oncreate中调用) 25 | * [2、开始加载](#2开始加载) 26 | * [3、加载结果回调](#3加载结果回调在你的请求成功和失败的回调中加入加载结果回调) 27 | * [4、解除绑定](#4解除绑定) 28 | * [为何要造这个看起来重复的轮子](#为何要造这个看起来重复的轮子) 29 | * [反馈与建议](#反馈与建议) 30 | 31 | # 初步配置 32 | ## 引入 33 | Step 1. Add it in your root build.gradle at the end of repositories: 34 | 35 | allprojects { 36 | repositories { 37 | ... 38 | maven { url 'https://jitpack.io' } 39 | } 40 | } 41 | Step 2. Add the dependency 42 | 43 | dependencies { 44 | implementation 'com.github.NoEndToLF:View-Load-ReTry:2.0.1' 45 | } 46 | ## 自定义加载状态页面 Adapter,继承 BaseLoadRetryAdapter,下面各方法都是按需被调用,取决于你主动设置的显示哪个Adapter。 47 | | 方法 |参数 | 作用 | 48 | | :-------- | :--------| :--: | 49 | | onLoadStart| View | 显示这个加载状态页面前开始前调用,用于你自定义页面中控件的初始化,此View为当前显示的加载页面View,以下方法中的View都是。 | 50 | | getCoverViewLayoutId | return R.layout | 加载页面的布局Layout | 51 | | onFalied| View,Ogject | 加载失败的回调(会在你主动调用错误页面对应的那个Adapter里调用),Object可以是任意的对象,方便你显示加载错误的原因| 52 | | onSuccess| View | 加载成功的回调(会在你设置的Load状态那个Adapter里调用),这里可以做一些加载动画的停止操作,另需要手动让View.Gone,暴露在这里是方便各位添加加载页面消失的动画| 53 | 54 | 自定义Adapter示例(Demo中normal用法) 55 | ``` java 56 | public class LoadAdapterForActivity extends BaseLoadRetryAdapter{ 57 | @Override 58 | public void onLoadStart(View view) { 59 | ((TextView)view.findViewById(R.id.tv_text)).setText("加载中 ..."); 60 | } 61 | @Override 62 | public void onFalied(View view, Object object) { 63 | } 64 | /**这里在加载完成的时候做了一个淡出动画*/ 65 | @Override 66 | public void onSuccess(View view) { 67 | AlphaAnimation alphaAnimation = new AlphaAnimation(1,0); 68 | alphaAnimation.setDuration(500); 69 | view.startAnimation(alphaAnimation); 70 | view.setVisibility(View.GONE); 71 | } 72 | 73 | @Override 74 | public int getCoverViewLayoutId() { 75 | return R.layout.load_activity; 76 | } 77 | } 78 | ``` 79 | ``` java 80 | /**默认给加载失败页面添加了点击事件,回调到retry方法,开始重试,重试时显示加载中Adapter对应的页面*/ 81 | public class NetErrorAdapterForActivity extends BaseLoadRetryAdapter{ 82 | @Override 83 | public void onLoadStart(View view) { 84 | ((TextView)view.findViewById(R.id.tv_retry)).setText("点击重新加载"); 85 | } 86 | 87 | @Override 88 | public void onFalied(View view, Object object) { 89 | ((ImageView) view.findViewById(R.id.iv_head)).setImageResource(R.mipmap.timeout); 90 | ((TextView)view.findViewById(R.id.tv_text)).setText((String)object); 91 | ((TextView)view.findViewById(R.id.tv_retry)).setVisibility(View.VISIBLE); 92 | } 93 | 94 | @Override 95 | public void onSuccess(View view) { 96 | 97 | } 98 | 99 | @Override 100 | public int getCoverViewLayoutId() { 101 | return R.layout.retry_activity; 102 | } 103 | } 104 | ``` 105 | ## 示例代码(Demo中normal用法):建议在 Application的 onCreate中进行初始化,有多少个Adapter就添加多少个,这里统一了入口是方便管理。 106 | ``` java 107 | LoadRetryManager.getInstance().addAdapter(new LoadAdapterForActivity()); 108 | LoadRetryManager.getInstance().addAdapter(new NetErrorAdapterForActivity());....... 109 | ``` 110 | # 最常规用法,针对一个View(针对多个View和针对一个View用法一致,流程都是针对某个View的) 111 | 112 | | 方法 |参数 | 作用 | 113 | | :-------- | :--------| :--| 114 | | register| View,LoadRetryRefreshListener | 注册 | 115 | | startLoad| View,Class | 开始加载,加载中类Adapter.Calss | 116 | | unRegister| View | 解除绑定| 117 | | unRegister| List | 解除多个View的绑定| 118 | | onSuccess | View | 加载成功,会调用View对应加载中Adapter的onSuccess方法| 119 | | onFailed   |View,Class,Object| 加载失败时显示加载失败类Adapter.Class对应的页面,并调用该Adapter的onFalied()方法,Object为加载失败原因| 120 | 121 | 122 | ### 1、注册,一般在 onCreate中调用 123 | ``` java 124 | LoadRetryManager.getInstance().register(view, new LoadRetryListener() { 125 | @Override 126 | public void load() { 127 | //执行你的网络请求 128 | //dosomething(); 129 | } 130 | 131 | @Override 132 | public void reTry() { 133 | //执行你的重试请求 134 | //dosomethingRetry(); 135 | } 136 | }); 137 | ``` 138 | ### 2、开始加载 139 | ``` java 140 | LoadRetryManager.getInstance().load(view, LoadAdapterForActivity.class); 141 | ``` 142 | ### 3、加载结果回调,在你的请求成功和失败的回调中加入加载结果回调 143 | ``` java 144 | @Override 145 | public void onSuccess(Integer value) { 146 | //加载成功你要做的事..... 147 | 148 | //加载结果回调 149 | LoadRetryManager.getInstance().onSuccess(view); 150 | } 151 | 152 | @Override 153 | public void onFailed(Throwable e) { 154 | //加载失败你要做的事..... 155 | 156 | //加载结果回调 157 | LoadRetryManager.getInstance().onFailed(view, NetErrorAdapterForActivity.class, "请检查网络连接"); 158 | 159 | } 160 | ``` 161 | ### 4、解除绑定 162 | ``` java 163 | //在Activity中 164 | Override 165 | protected void onDestroy() { 166 | super.onDestroy(); 167 | LoadRetryManager.getInstance().unRegister(view); 168 | 169 | //加载多个View时建议在BaseActivity中封装方法,维护一个List,每注册一个加载View就Add一次,解绑时方便操作 170 | LoadRetryManager.getInstance().unRegister(list); 171 | } 172 | ``` 173 | ``` java 174 | //在Fragment中 175 | @Override 176 | public void onDestroyView() { 177 | super.onDestroyView(); 178 | LoadRetryManager.getInstance().unRegister(view); 179 | 180 | //加载多个View时建议在BaseFragment中封装方法,维护一个List,每注册一个加载View就Add一次,解绑时方便操作 181 | LoadRetryManager.getInstance().unRegister(list); 182 | } 183 | ``` 184 | # 为何要造这个看起来重复的轮子 185 | 目前好多开源的加载反馈框架大多是针对Activity和Fragment的,原理都是从根上替换加载布局,但是有个缺点,反馈布局的作用域太大了,不够灵活,现在闲的蛋疼造这个轮子也是为了灵活性,比如说Sample中的同一个页面要加载3块内容的时候,这个轮子的优势就显示出来了,而且原View具有的基本特性加载反馈页面依然包含。 186 | 187 | # 反馈与建议 188 | - 邮箱: 189 | 190 | # License 191 | ``` 192 | Copyright (c) [2018] [static] 193 | 194 | Permission is hereby granted, free of charge, to any person obtaining a copy 195 | of this software and associated documentation files (the "Software"), to deal 196 | in the Software without restriction, including without limitation the rights 197 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 198 | copies of the Software, and to permit persons to whom the Software is 199 | furnished to do so, subject to the following conditions: 200 | 201 | The above copyright notice and this permission notice shall be included in all 202 | copies or substantial portions of the Software. 203 | 204 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 205 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 206 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 207 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 208 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 209 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 210 | SOFTWARE. 211 | ``` 212 | --------- 213 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 28 5 | defaultConfig { 6 | applicationId "com.aiceking.view_load_retry" 7 | minSdkVersion 16 8 | targetSdkVersion 28 9 | versionCode 1 10 | versionName "1.0" 11 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 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 | implementation 'com.android.support:appcompat-v7:28.0.0' 24 | implementation 'com.android.support.constraint:constraint-layout:1.1.3' 25 | testImplementation 'junit:junit:4.12' 26 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 27 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 28 | // implementation project(':viewloadretrylibrary') 29 | implementation 'com.github.NoEndToLF:View-Load-ReTry:2.0.1' 30 | implementation 'com.jaywei:mdprogress:1.0.2' /*加载动画View*/ 31 | implementation 'com.github.NoEndToLF:LazyBaseFragment:1.0.4'//lazyFragment 32 | implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.30'//万能adapter 33 | implementation 'com.jakewharton:butterknife:8.8.1' 34 | annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1' 35 | implementation 'io.reactivex.rxjava2:rxjava:2.0.1' 36 | implementation 'io.reactivex.rxjava2:rxandroid:2.0.1' 37 | implementation "com.android.support:design:28.+" 38 | implementation 'com.gyf.barlibrary:barlibrary:2.3.0'//沉浸式状态栏,透明状态栏 39 | debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.6.2' 40 | releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.6.2' 41 | // Optional, if you use support library fragments: 42 | debugImplementation 'com.squareup.leakcanary:leakcanary-support-fragment:1.6.2' 43 | } 44 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/aiceking/view_load_retry/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.aiceking.view_load_retry; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.aiceking.view_load_retry", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/java/com/aiceking/view_load_retry/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.aiceking.view_load_retry; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.support.v4.app.FragmentActivity; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.view.View; 8 | import android.widget.Button; 9 | 10 | import com.aiceking.view_load_retry.activity.LoadFragmentActivity; 11 | import com.aiceking.view_load_retry.activity.NormalActivity; 12 | 13 | import butterknife.BindView; 14 | import butterknife.ButterKnife; 15 | import butterknife.OnClick; 16 | 17 | public class MainActivity extends AppCompatActivity { 18 | @BindView(R.id.btn_normal) 19 | Button btnNormal; 20 | @BindView(R.id.btn_fix) 21 | Button btnFix; 22 | 23 | @Override 24 | protected void onCreate(Bundle savedInstanceState) { 25 | super.onCreate(savedInstanceState); 26 | setContentView(R.layout.activity_main); 27 | ButterKnife.bind(this); 28 | 29 | } 30 | 31 | 32 | @OnClick({R.id.btn_normal, R.id.btn_fix}) 33 | public void onViewClicked(View view) { 34 | switch (view.getId()) { 35 | case R.id.btn_normal: 36 | startActivity(new Intent(this, NormalActivity.class)); 37 | break; 38 | case R.id.btn_fix: 39 | startActivity(new Intent(this, LoadFragmentActivity.class)); 40 | break; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/com/aiceking/view_load_retry/activity/LoadFragmentActivity.java: -------------------------------------------------------------------------------- 1 | package com.aiceking.view_load_retry.activity; 2 | 3 | import android.os.Bundle; 4 | import android.support.design.widget.AppBarLayout; 5 | import android.support.design.widget.TabLayout; 6 | import android.support.v4.app.Fragment; 7 | import android.support.v4.app.FragmentManager; 8 | import android.support.v4.app.FragmentStatePagerAdapter; 9 | import android.support.v4.view.ViewPager; 10 | import android.support.v7.app.AppCompatActivity; 11 | import android.support.v7.widget.Toolbar; 12 | import android.view.View; 13 | import android.widget.ImageView; 14 | import android.widget.LinearLayout; 15 | import android.widget.TextView; 16 | 17 | import com.aiceking.view_load_retry.R; 18 | import com.aiceking.view_load_retry.fragment.TestFragment; 19 | import com.aiceking.view_load_retry.loadretryadapter.forimageview.LoadAdapterForImageView; 20 | import com.aiceking.view_load_retry.loadretryadapter.fortablayout.LoadAdapterForTabLayout; 21 | import com.aiceking.view_load_retry.loadretryadapter.forimageview.NetErrorAdapterForImageView; 22 | import com.aiceking.view_load_retry.loadretryadapter.fortablayout.NetErrorAdapterForTabLayout; 23 | import com.aiceking.view_load_retry.util.ToolBarUtil; 24 | import com.aiceking.viewloadretrylibrary.listener.LoadRetryListener; 25 | import com.aiceking.viewloadretrylibrary.manager.LoadRetryManager; 26 | import com.gyf.barlibrary.ImmersionBar; 27 | 28 | import java.util.ArrayList; 29 | import java.util.List; 30 | 31 | import butterknife.BindView; 32 | import butterknife.ButterKnife; 33 | import butterknife.OnClick; 34 | import io.reactivex.Observable; 35 | import io.reactivex.ObservableEmitter; 36 | import io.reactivex.ObservableOnSubscribe; 37 | import io.reactivex.Observer; 38 | import io.reactivex.android.schedulers.AndroidSchedulers; 39 | import io.reactivex.disposables.Disposable; 40 | import io.reactivex.schedulers.Schedulers; 41 | /**测试提交*/ 42 | public class LoadFragmentActivity extends AppCompatActivity { 43 | 44 | @BindView(R.id.iv_head) 45 | ImageView ivHead; 46 | @BindView(R.id.tv_name) 47 | TextView tvName; 48 | @BindView(R.id.toolbar) 49 | Toolbar toolbar; 50 | @BindView(R.id.tablayout) 51 | TabLayout tablayout; 52 | @BindView(R.id.appbar) 53 | AppBarLayout appbar; 54 | @BindView(R.id.vp) 55 | ViewPager vp; 56 | @BindView(R.id.linear_back) 57 | LinearLayout linearBack; 58 | private List list_fragments; 59 | private List list_titles; 60 | private List contentViewList; 61 | @Override 62 | protected void onCreate(Bundle savedInstanceState) { 63 | super.onCreate(savedInstanceState); 64 | setContentView(R.layout.activity_load_fragment); 65 | ButterKnife.bind(this); 66 | contentViewList=new ArrayList<>(); 67 | contentViewList.add(ivHead); 68 | contentViewList.add(tablayout); 69 | initToolBar(); 70 | initData(); 71 | initViewPagerAndTabLayout(); 72 | loadRetryImageView(); 73 | loadRetryTablayout(); 74 | } 75 | 76 | private void loadRetryImageView() { 77 | LoadRetryManager.getInstance().register(ivHead, new LoadRetryListener() { 78 | @Override 79 | public void load() { 80 | doSomethingOne(false); 81 | } 82 | 83 | @Override 84 | public void reTry() { 85 | doSomethingOne(true); 86 | } 87 | }); 88 | LoadRetryManager.getInstance().load(ivHead, LoadAdapterForImageView.class); 89 | } 90 | 91 | private void loadRetryTablayout() { 92 | LoadRetryManager.getInstance().register(tablayout, new LoadRetryListener() { 93 | @Override 94 | public void load() { 95 | doSomethingTwo(false); 96 | } 97 | 98 | @Override 99 | public void reTry() { 100 | doSomethingTwo(true); 101 | } 102 | }); 103 | LoadRetryManager.getInstance().load(tablayout, LoadAdapterForTabLayout.class); 104 | } 105 | 106 | public void doSomethingOne(final boolean isSuccess) { 107 | Observable.create(new ObservableOnSubscribe() { 108 | @Override 109 | public void subscribe(ObservableEmitter emitter) throws Exception { 110 | Thread.sleep(3000); 111 | if (isSuccess) { 112 | emitter.onNext(0); 113 | } else { 114 | emitter.onNext(2); 115 | } 116 | } 117 | }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { 118 | @Override 119 | public void onSubscribe(Disposable d) { 120 | 121 | } 122 | 123 | @Override 124 | public void onNext(Integer value) { 125 | if (value == 0) { 126 | LoadRetryManager.getInstance().onSuccess(ivHead); 127 | } else { 128 | LoadRetryManager.getInstance().onFailed(ivHead, NetErrorAdapterForImageView.class, "请检查网络连接"); 129 | } 130 | } 131 | 132 | @Override 133 | public void onError(Throwable e) { 134 | } 135 | 136 | @Override 137 | public void onComplete() { 138 | } 139 | }); 140 | } 141 | 142 | public void doSomethingTwo(final boolean isSuccess) { 143 | Observable.create(new ObservableOnSubscribe() { 144 | @Override 145 | public void subscribe(ObservableEmitter emitter) throws Exception { 146 | Thread.sleep(3000); 147 | if (isSuccess) { 148 | emitter.onNext(0); 149 | } else { 150 | emitter.onNext(2); 151 | } 152 | } 153 | }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { 154 | @Override 155 | public void onSubscribe(Disposable d) { 156 | 157 | } 158 | 159 | @Override 160 | public void onNext(Integer value) { 161 | if (value == 0) { 162 | LoadRetryManager.getInstance().onSuccess(tablayout); 163 | } else { 164 | LoadRetryManager.getInstance().onFailed(tablayout, NetErrorAdapterForTabLayout.class, "请检查网络连接"); 165 | } 166 | } 167 | 168 | @Override 169 | public void onError(Throwable e) { 170 | } 171 | 172 | @Override 173 | public void onComplete() { 174 | } 175 | }); 176 | } 177 | 178 | private void initData() { 179 | list_titles = new ArrayList<>(); 180 | list_fragments = new ArrayList<>(); 181 | list_titles.add("测试一"); 182 | list_titles.add("测试二"); 183 | list_fragments.add(new TestFragment()); 184 | list_fragments.add(new TestFragment()); 185 | for (String title : list_titles) { 186 | tablayout.addTab(tablayout.newTab().setText(title)); 187 | } 188 | } 189 | 190 | private void initViewPagerAndTabLayout() { 191 | vp.setAdapter(new MyAdapter(getSupportFragmentManager())); 192 | tablayout.setupWithViewPager(vp); 193 | } 194 | 195 | private void initToolBar() { 196 | setSupportActionBar(toolbar); 197 | ToolBarUtil.setToolbarPaddingTop(toolbar, this); 198 | ImmersionBar.with(this).transparentStatusBar().init(); 199 | appbar.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() { 200 | @Override 201 | public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) { 202 | toolbar.setBackgroundColor(ToolBarUtil.changeAlpha(getResources().getColor(R.color.blue), Math.abs(verticalOffset * 1.0f) / appBarLayout.getTotalScrollRange())); 203 | tvName.setTextColor(ToolBarUtil.changeAlpha(getResources().getColor(R.color.white), Math.abs(verticalOffset * 1.0f) / appBarLayout.getTotalScrollRange())); 204 | } 205 | }); 206 | } 207 | 208 | @OnClick(R.id.linear_back) 209 | public void onViewClicked() { 210 | finish(); 211 | } 212 | 213 | public class MyAdapter extends FragmentStatePagerAdapter { 214 | 215 | public MyAdapter(FragmentManager fm) { 216 | super(fm); 217 | } 218 | 219 | @Override 220 | public CharSequence getPageTitle(int position) { 221 | return list_titles.get(position); 222 | } 223 | 224 | @Override 225 | public Fragment getItem(int position) { 226 | return list_fragments.get(position); 227 | } 228 | 229 | @Override 230 | public int getCount() { 231 | return list_fragments.size(); 232 | } 233 | } 234 | 235 | @Override 236 | protected void onDestroy() { 237 | super.onDestroy(); 238 | ImmersionBar.with(this).destroy(); 239 | LoadRetryManager.getInstance().unRegister(contentViewList); 240 | // LoadRetryManager.getInstance().unRegister(ivHead); 241 | // LoadRetryManager.getInstance().unRegister(tablayout); 242 | } 243 | } 244 | -------------------------------------------------------------------------------- /app/src/main/java/com/aiceking/view_load_retry/activity/NormalActivity.java: -------------------------------------------------------------------------------- 1 | package com.aiceking.view_load_retry.activity; 2 | 3 | import android.os.Bundle; 4 | import android.support.v4.widget.SwipeRefreshLayout; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.support.v7.widget.LinearLayoutManager; 7 | import android.support.v7.widget.RecyclerView; 8 | import android.support.v7.widget.Toolbar; 9 | import android.widget.LinearLayout; 10 | import android.widget.TextView; 11 | 12 | import com.aiceking.view_load_retry.R; 13 | import com.aiceking.view_load_retry.fragment.adapter.TestAdapter; 14 | import com.aiceking.view_load_retry.loadretryadapter.foractivity.LoadAdapterForActivity; 15 | import com.aiceking.view_load_retry.loadretryadapter.foractivity.NetErrorAdapterForActivity; 16 | import com.aiceking.viewloadretrylibrary.listener.LoadRetryListener; 17 | import com.aiceking.viewloadretrylibrary.manager.LoadRetryManager; 18 | import com.gyf.barlibrary.ImmersionBar; 19 | 20 | import java.util.ArrayList; 21 | import java.util.List; 22 | 23 | import butterknife.BindView; 24 | import butterknife.ButterKnife; 25 | import butterknife.OnClick; 26 | import io.reactivex.Observable; 27 | import io.reactivex.ObservableEmitter; 28 | import io.reactivex.ObservableOnSubscribe; 29 | import io.reactivex.Observer; 30 | import io.reactivex.android.schedulers.AndroidSchedulers; 31 | import io.reactivex.disposables.Disposable; 32 | import io.reactivex.schedulers.Schedulers; 33 | 34 | public class NormalActivity extends AppCompatActivity { 35 | 36 | @BindView(R.id.linear_back) 37 | LinearLayout linearBack; 38 | @BindView(R.id.tv_name) 39 | TextView tvName; 40 | @BindView(R.id.toolbar) 41 | Toolbar toolbar; 42 | @BindView(R.id.recycler) 43 | RecyclerView recycler; 44 | @BindView(R.id.sw) 45 | SwipeRefreshLayout sw; 46 | private List stringList; 47 | private TestAdapter testAdapter; 48 | 49 | @Override 50 | protected void onCreate(Bundle savedInstanceState) { 51 | super.onCreate(savedInstanceState); 52 | setContentView(R.layout.activity_normal); 53 | ButterKnife.bind(this); 54 | ImmersionBar.with(this).statusBarColor(R.color.blue).fitsSystemWindows(true).init(); 55 | 56 | tvName.setText("常规使用"); 57 | stringList = new ArrayList<>(); 58 | testAdapter = new TestAdapter(R.layout.recycle_test, stringList); 59 | LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false); 60 | recycler.setLayoutManager(layoutManager); 61 | recycler.setAdapter(testAdapter); 62 | sw.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { 63 | @Override 64 | public void onRefresh() { 65 | doSomethingOne(false); 66 | } 67 | }); 68 | loadRetryRecycleview(); 69 | } 70 | 71 | private void loadRetryRecycleview() { 72 | LoadRetryManager.getInstance().register(sw, new LoadRetryListener() { 73 | @Override 74 | public void load() { 75 | doSomethingOne(false); 76 | } 77 | 78 | @Override 79 | public void reTry() { 80 | doSomethingOne(true); 81 | } 82 | }); 83 | LoadRetryManager.getInstance().load(sw, LoadAdapterForActivity.class); 84 | 85 | } 86 | 87 | public void doSomethingOne(final boolean isSuccess) { 88 | Observable.create(new ObservableOnSubscribe() { 89 | @Override 90 | public void subscribe(ObservableEmitter emitter) throws Exception { 91 | Thread.sleep(3000); 92 | if (isSuccess) { 93 | emitter.onNext(0); 94 | } else { 95 | emitter.onNext(2); 96 | } 97 | } 98 | }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { 99 | @Override 100 | public void onSubscribe(Disposable d) { 101 | 102 | } 103 | 104 | @Override 105 | public void onNext(Integer value) { 106 | sw.setRefreshing(false); 107 | if (value == 0) { 108 | LoadRetryManager.getInstance().onSuccess(sw); 109 | for (int i = 0; i < 20; i++) { 110 | stringList.add("测试数据:" + (i + 1)); 111 | } 112 | testAdapter.notifyDataSetChanged(); 113 | } else { 114 | LoadRetryManager.getInstance().onFailed(sw, NetErrorAdapterForActivity.class, "请检查网络连接"); 115 | } 116 | } 117 | 118 | @Override 119 | public void onError(Throwable e) { 120 | } 121 | 122 | @Override 123 | public void onComplete() { 124 | } 125 | }); 126 | } 127 | 128 | @OnClick(R.id.linear_back) 129 | public void onViewClicked() { 130 | finish(); 131 | } 132 | 133 | @Override 134 | protected void onDestroy() { 135 | super.onDestroy(); 136 | ImmersionBar.with(this).destroy(); 137 | LoadRetryManager.getInstance().unRegister(sw); 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /app/src/main/java/com/aiceking/view_load_retry/application/MyApplication.java: -------------------------------------------------------------------------------- 1 | package com.aiceking.view_load_retry.application; 2 | 3 | import android.app.Application; 4 | 5 | import com.aiceking.view_load_retry.loadretryadapter.foractivity.LoadAdapterForActivity; 6 | import com.aiceking.view_load_retry.loadretryadapter.forfragment.LoadAdapterForFragment; 7 | import com.aiceking.view_load_retry.loadretryadapter.fortablayout.LoadAdapterForTabLayout; 8 | import com.aiceking.view_load_retry.loadretryadapter.foractivity.NetErrorAdapterForActivity; 9 | import com.aiceking.view_load_retry.loadretryadapter.forfragment.NetErrorAdapterForFragment; 10 | import com.aiceking.view_load_retry.loadretryadapter.forimageview.NetErrorAdapterForImageView; 11 | import com.aiceking.view_load_retry.loadretryadapter.forimageview.LoadAdapterForImageView; 12 | import com.aiceking.view_load_retry.loadretryadapter.fortablayout.NetErrorAdapterForTabLayout; 13 | import com.aiceking.viewloadretrylibrary.manager.LoadRetryManager; 14 | import com.squareup.leakcanary.LeakCanary; 15 | /**测试提交*/ 16 | public class MyApplication extends Application{ 17 | @Override 18 | public void onCreate() { 19 | super.onCreate(); 20 | if (LeakCanary.isInAnalyzerProcess(this)) { 21 | // This process is dedicated to LeakCanary for heap analysis. 22 | // You should not init your app in this process. 23 | return; 24 | } 25 | LeakCanary.install(this); 26 | LoadRetryManager.getInstance().addAdapter(new LoadAdapterForImageView()); 27 | LoadRetryManager.getInstance().addAdapter(new NetErrorAdapterForImageView()); 28 | LoadRetryManager.getInstance().addAdapter(new LoadAdapterForTabLayout()); 29 | LoadRetryManager.getInstance().addAdapter(new NetErrorAdapterForTabLayout()); 30 | LoadRetryManager.getInstance().addAdapter(new LoadAdapterForFragment()); 31 | LoadRetryManager.getInstance().addAdapter(new NetErrorAdapterForFragment()); 32 | LoadRetryManager.getInstance().addAdapter(new LoadAdapterForActivity()); 33 | LoadRetryManager.getInstance().addAdapter(new NetErrorAdapterForActivity()); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/com/aiceking/view_load_retry/fragment/TestFragment.java: -------------------------------------------------------------------------------- 1 | package com.aiceking.view_load_retry.fragment; 2 | 3 | import android.content.Context; 4 | import android.support.annotation.Nullable; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.support.v7.widget.LinearLayoutManager; 7 | import android.support.v7.widget.RecyclerView; 8 | import android.view.LayoutInflater; 9 | import android.view.View; 10 | import android.view.ViewGroup; 11 | 12 | import com.aiceking.view_load_retry.R; 13 | import com.aiceking.view_load_retry.fragment.adapter.TestAdapter; 14 | import com.aiceking.view_load_retry.loadretryadapter.forfragment.LoadAdapterForFragment; 15 | import com.aiceking.view_load_retry.loadretryadapter.forfragment.NetErrorAdapterForFragment; 16 | import com.aiceking.viewloadretrylibrary.listener.LoadRetryListener; 17 | import com.aiceking.viewloadretrylibrary.manager.LoadRetryManager; 18 | import com.android.lazyfragmentlibrary.LazyBaseFragment; 19 | 20 | import java.util.ArrayList; 21 | import java.util.List; 22 | 23 | import butterknife.BindView; 24 | import butterknife.ButterKnife; 25 | import io.reactivex.Observable; 26 | import io.reactivex.ObservableEmitter; 27 | import io.reactivex.ObservableOnSubscribe; 28 | import io.reactivex.Observer; 29 | import io.reactivex.android.schedulers.AndroidSchedulers; 30 | import io.reactivex.disposables.Disposable; 31 | import io.reactivex.schedulers.Schedulers; 32 | 33 | public class TestFragment extends LazyBaseFragment { 34 | @BindView(R.id.recycler) 35 | RecyclerView recycler; 36 | private AppCompatActivity activity; 37 | private View contentView; 38 | private List stringList; 39 | private TestAdapter testAdapter; 40 | @Override 41 | public void onAttach(Context context) { 42 | super.onAttach(context); 43 | activity = (AppCompatActivity) context; 44 | } 45 | 46 | @Override 47 | protected View setFragmentView(LayoutInflater layoutInflater, @Nullable ViewGroup viewGroup) { 48 | contentView = layoutInflater.inflate(R.layout.fragment_test, viewGroup, false); 49 | ButterKnife.bind(this, contentView); 50 | stringList=new ArrayList<>(); 51 | loadRetryRecycleview(); 52 | testAdapter=new TestAdapter(R.layout.recycle_test,stringList); 53 | LinearLayoutManager layoutManager=new LinearLayoutManager(activity, LinearLayoutManager.VERTICAL, false); 54 | recycler.setLayoutManager(layoutManager); 55 | recycler.setAdapter(testAdapter); 56 | return contentView; 57 | } 58 | private void loadRetryRecycleview() { 59 | LoadRetryManager.getInstance().register(recycler, new LoadRetryListener() { 60 | @Override 61 | public void load() { 62 | doSomethingOne(false); 63 | } 64 | 65 | @Override 66 | public void reTry() { 67 | doSomethingOne(true); 68 | } 69 | }); 70 | } 71 | @Override 72 | protected void loadData() { 73 | LoadRetryManager.getInstance().load(recycler, LoadAdapterForFragment.class); 74 | 75 | } 76 | public void doSomethingOne(final boolean isSuccess) { 77 | Observable.create(new ObservableOnSubscribe() { 78 | @Override 79 | public void subscribe(ObservableEmitter emitter) throws Exception { 80 | Thread.sleep(3000); 81 | if (isSuccess) { 82 | emitter.onNext(0); 83 | } else { 84 | emitter.onNext(2); 85 | } 86 | } 87 | }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer() { 88 | @Override 89 | public void onSubscribe(Disposable d) { 90 | 91 | } 92 | 93 | @Override 94 | public void onNext(Integer value) { 95 | if (value == 0) { 96 | LoadRetryManager.getInstance().onSuccess(recycler); 97 | for (int i=0;i<20;i++){ 98 | stringList.add("测试数据:"+(i+1)); 99 | } 100 | testAdapter.notifyDataSetChanged(); 101 | } else { 102 | LoadRetryManager.getInstance().onFailed(recycler, NetErrorAdapterForFragment.class, "请检查网络连接"); 103 | } 104 | } 105 | 106 | @Override 107 | public void onError(Throwable e) { 108 | } 109 | 110 | @Override 111 | public void onComplete() { 112 | } 113 | }); 114 | } 115 | 116 | @Override 117 | protected void stopLoadData() { 118 | 119 | 120 | } 121 | 122 | @Override 123 | public void onDestroyView() { 124 | super.onDestroyView(); 125 | LoadRetryManager.getInstance().unRegister(recycler); 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /app/src/main/java/com/aiceking/view_load_retry/fragment/adapter/TestAdapter.java: -------------------------------------------------------------------------------- 1 | package com.aiceking.view_load_retry.fragment.adapter; 2 | 3 | import android.support.annotation.Nullable; 4 | import android.view.View; 5 | import android.widget.TextView; 6 | 7 | import com.aiceking.view_load_retry.R; 8 | import com.chad.library.adapter.base.BaseQuickAdapter; 9 | import com.chad.library.adapter.base.BaseViewHolder; 10 | 11 | import java.util.List; 12 | 13 | public class TestAdapter extends BaseQuickAdapter{ 14 | public TestAdapter(int layoutResId, @Nullable List data) { 15 | super(layoutResId, data); 16 | } 17 | 18 | @Override 19 | protected void convert(BaseViewHolder helper, String item) { 20 | ((TextView)helper.getView(R.id.tv_text)).setText(item); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/com/aiceking/view_load_retry/loadretryadapter/foractivity/LoadAdapterForActivity.java: -------------------------------------------------------------------------------- 1 | package com.aiceking.view_load_retry.loadretryadapter.foractivity; 2 | 3 | import android.view.View; 4 | import android.view.animation.AlphaAnimation; 5 | import android.widget.TextView; 6 | 7 | import com.aiceking.view_load_retry.R; 8 | import com.aiceking.viewloadretrylibrary.adapter.BaseLoadRetryAdapter; 9 | import com.jaywei.mdprogress.CircularProgressBar; 10 | 11 | public class LoadAdapterForActivity extends BaseLoadRetryAdapter{ 12 | @Override 13 | public void onLoadStart(View view) { 14 | ((TextView)view.findViewById(R.id.tv_text)).setText("加载中 ..."); 15 | } 16 | @Override 17 | public void onFalied(View view, Object object) { 18 | } 19 | /**这里在加载完成的时候做了一个淡出动画*/ 20 | @Override 21 | public void onSuccess(View view) { 22 | AlphaAnimation alphaAnimation = new AlphaAnimation(1,0); 23 | alphaAnimation.setDuration(500); 24 | view.startAnimation(alphaAnimation); 25 | view.setVisibility(View.GONE); 26 | } 27 | 28 | @Override 29 | public int getCoverViewLayoutId() { 30 | return R.layout.load_activity; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/com/aiceking/view_load_retry/loadretryadapter/foractivity/NetErrorAdapterForActivity.java: -------------------------------------------------------------------------------- 1 | package com.aiceking.view_load_retry.loadretryadapter.foractivity; 2 | 3 | import android.view.View; 4 | import android.view.animation.AlphaAnimation; 5 | import android.widget.ImageView; 6 | import android.widget.TextView; 7 | 8 | import com.aiceking.view_load_retry.R; 9 | import com.aiceking.viewloadretrylibrary.adapter.BaseLoadRetryAdapter; 10 | 11 | public class NetErrorAdapterForActivity extends BaseLoadRetryAdapter{ 12 | @Override 13 | public void onLoadStart(View view) { 14 | ((TextView)view.findViewById(R.id.tv_retry)).setText("点击重新加载"); 15 | } 16 | 17 | @Override 18 | public void onFalied(View view, Object object) { 19 | ((ImageView) view.findViewById(R.id.iv_head)).setImageResource(R.mipmap.timeout); 20 | ((TextView)view.findViewById(R.id.tv_text)).setText((String)object); 21 | ((TextView)view.findViewById(R.id.tv_retry)).setVisibility(View.VISIBLE); 22 | } 23 | 24 | @Override 25 | public void onSuccess(View view) { 26 | AlphaAnimation alphaAnimation = new AlphaAnimation(1,0); 27 | alphaAnimation.setDuration(500); 28 | view.startAnimation(alphaAnimation); 29 | view.setVisibility(View.GONE); 30 | } 31 | 32 | @Override 33 | public int getCoverViewLayoutId() { 34 | return R.layout.retry_activity; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/com/aiceking/view_load_retry/loadretryadapter/forfragment/LoadAdapterForFragment.java: -------------------------------------------------------------------------------- 1 | package com.aiceking.view_load_retry.loadretryadapter.forfragment; 2 | 3 | import android.view.View; 4 | import android.view.animation.AlphaAnimation; 5 | import android.widget.TextView; 6 | 7 | import com.aiceking.view_load_retry.R; 8 | import com.aiceking.viewloadretrylibrary.adapter.BaseLoadRetryAdapter; 9 | import com.jaywei.mdprogress.CircularProgressBar; 10 | 11 | public class LoadAdapterForFragment extends BaseLoadRetryAdapter{ 12 | @Override 13 | public void onLoadStart(View view) { 14 | ((TextView)view.findViewById(R.id.tv_text)).setText("加载中 ..."); 15 | } 16 | @Override 17 | public void onFalied(View view, Object object) { 18 | } 19 | 20 | @Override 21 | public void onSuccess(View view) { 22 | AlphaAnimation alphaAnimation = new AlphaAnimation(1,0); 23 | alphaAnimation.setDuration(500); 24 | view.startAnimation(alphaAnimation); 25 | view.setVisibility(View.GONE); 26 | } 27 | 28 | @Override 29 | public int getCoverViewLayoutId() { 30 | return R.layout.load_fragment; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/com/aiceking/view_load_retry/loadretryadapter/forfragment/NetErrorAdapterForFragment.java: -------------------------------------------------------------------------------- 1 | package com.aiceking.view_load_retry.loadretryadapter.forfragment; 2 | 3 | import android.view.View; 4 | import android.view.animation.AlphaAnimation; 5 | import android.widget.ImageView; 6 | import android.widget.TextView; 7 | 8 | import com.aiceking.view_load_retry.R; 9 | import com.aiceking.viewloadretrylibrary.adapter.BaseLoadRetryAdapter; 10 | 11 | public class NetErrorAdapterForFragment extends BaseLoadRetryAdapter{ 12 | @Override 13 | public void onLoadStart(View view) { 14 | ((TextView)view.findViewById(R.id.tv_retry)).setText("点击重新加载"); 15 | } 16 | @Override 17 | public void onFalied(View view, Object object) { 18 | ((ImageView) view.findViewById(R.id.iv_head)).setImageResource(R.mipmap.timeout); 19 | ((TextView)view.findViewById(R.id.tv_text)).setText((String)object); 20 | ((TextView)view.findViewById(R.id.tv_retry)).setVisibility(View.VISIBLE); 21 | } 22 | @Override 23 | public void onSuccess(View view) { 24 | AlphaAnimation alphaAnimation = new AlphaAnimation(1,0); 25 | alphaAnimation.setDuration(500); 26 | view.startAnimation(alphaAnimation); 27 | view.setVisibility(View.GONE); 28 | } 29 | 30 | @Override 31 | public int getCoverViewLayoutId() { 32 | return R.layout.retry_fragment; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/java/com/aiceking/view_load_retry/loadretryadapter/forimageview/LoadAdapterForImageView.java: -------------------------------------------------------------------------------- 1 | package com.aiceking.view_load_retry.loadretryadapter.forimageview; 2 | 3 | import android.view.View; 4 | import android.view.animation.AlphaAnimation; 5 | import android.widget.TextView; 6 | 7 | import com.aiceking.view_load_retry.R; 8 | import com.aiceking.viewloadretrylibrary.adapter.BaseLoadRetryAdapter; 9 | import com.jaywei.mdprogress.CircularProgressBar; 10 | 11 | public class LoadAdapterForImageView extends BaseLoadRetryAdapter{ 12 | @Override 13 | public void onLoadStart(View view) { 14 | ((TextView)view.findViewById(R.id.tv_text)).setText("加载中 ..."); 15 | } 16 | @Override 17 | public void onFalied(View view, Object object) { 18 | } 19 | 20 | @Override 21 | public void onSuccess(View view) { 22 | AlphaAnimation alphaAnimation = new AlphaAnimation(1,0); 23 | alphaAnimation.setDuration(500); 24 | view.startAnimation(alphaAnimation); 25 | view.setVisibility(View.GONE); 26 | } 27 | 28 | @Override 29 | public int getCoverViewLayoutId() { 30 | return R.layout.load_imageview; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/com/aiceking/view_load_retry/loadretryadapter/forimageview/NetErrorAdapterForImageView.java: -------------------------------------------------------------------------------- 1 | package com.aiceking.view_load_retry.loadretryadapter.forimageview; 2 | 3 | import android.view.View; 4 | import android.view.animation.AlphaAnimation; 5 | import android.widget.ImageView; 6 | import android.widget.TextView; 7 | 8 | import com.aiceking.view_load_retry.R; 9 | import com.aiceking.viewloadretrylibrary.adapter.BaseLoadRetryAdapter; 10 | 11 | public class NetErrorAdapterForImageView extends BaseLoadRetryAdapter{ 12 | @Override 13 | public void onLoadStart(View view) { 14 | ((TextView)view.findViewById(R.id.tv_retry)).setText("点击重新加载"); 15 | } 16 | @Override 17 | public void onFalied(View view, Object object) { 18 | ((ImageView) view.findViewById(R.id.iv_head)).setImageResource(R.mipmap.timeout); 19 | ((TextView)view.findViewById(R.id.tv_text)).setText((String)object); 20 | ((TextView)view.findViewById(R.id.tv_retry)).setVisibility(View.VISIBLE); 21 | } 22 | @Override 23 | public void onSuccess(View view) { 24 | AlphaAnimation alphaAnimation = new AlphaAnimation(1,0); 25 | alphaAnimation.setDuration(500); 26 | view.startAnimation(alphaAnimation); 27 | view.setVisibility(View.GONE); 28 | } 29 | 30 | @Override 31 | public int getCoverViewLayoutId() { 32 | return R.layout.retry_imageview; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/java/com/aiceking/view_load_retry/loadretryadapter/fortablayout/LoadAdapterForTabLayout.java: -------------------------------------------------------------------------------- 1 | package com.aiceking.view_load_retry.loadretryadapter.fortablayout; 2 | 3 | import android.view.View; 4 | import android.view.animation.AlphaAnimation; 5 | import android.widget.TextView; 6 | 7 | import com.aiceking.view_load_retry.R; 8 | import com.aiceking.viewloadretrylibrary.adapter.BaseLoadRetryAdapter; 9 | import com.jaywei.mdprogress.CircularProgressBar; 10 | 11 | public class LoadAdapterForTabLayout extends BaseLoadRetryAdapter{ 12 | @Override 13 | public void onLoadStart(View view) { 14 | ((TextView)view.findViewById(R.id.tv_text)).setText("加载中 ..."); 15 | } 16 | @Override 17 | public void onFalied(View view, Object object) { 18 | } 19 | 20 | @Override 21 | public void onSuccess(View view) { 22 | AlphaAnimation alphaAnimation = new AlphaAnimation(1,0); 23 | alphaAnimation.setDuration(500); 24 | view.startAnimation(alphaAnimation); 25 | view.setVisibility(View.GONE); 26 | } 27 | 28 | @Override 29 | public int getCoverViewLayoutId() { 30 | return R.layout.load_tablayout; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/com/aiceking/view_load_retry/loadretryadapter/fortablayout/NetErrorAdapterForTabLayout.java: -------------------------------------------------------------------------------- 1 | package com.aiceking.view_load_retry.loadretryadapter.fortablayout; 2 | 3 | import android.view.View; 4 | import android.view.animation.AlphaAnimation; 5 | import android.widget.ImageView; 6 | import android.widget.TextView; 7 | 8 | import com.aiceking.view_load_retry.R; 9 | import com.aiceking.viewloadretrylibrary.adapter.BaseLoadRetryAdapter; 10 | 11 | public class NetErrorAdapterForTabLayout extends BaseLoadRetryAdapter{ 12 | @Override 13 | public void onLoadStart(View view) { 14 | } 15 | 16 | @Override 17 | public void onFalied(View view, Object object) { 18 | ((TextView)view.findViewById(R.id.tv_text)).setText((String)object+",点击重新加载"); 19 | } 20 | 21 | @Override 22 | public void onSuccess(View view) { 23 | 24 | } 25 | 26 | @Override 27 | public int getCoverViewLayoutId() { 28 | return R.layout.retry_tablayout; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/com/aiceking/view_load_retry/util/ToolBarUtil.java: -------------------------------------------------------------------------------- 1 | package com.aiceking.view_load_retry.util; 2 | 3 | import android.content.Context; 4 | import android.content.res.Resources; 5 | import android.graphics.Color; 6 | import android.support.v7.widget.Toolbar; 7 | 8 | public class ToolBarUtil { 9 | public static void setToolbarPaddingTop(Toolbar toolbar,Context context) { 10 | toolbar.setPadding(0, getStatusBarHeight(context), 0, 0); 11 | } 12 | 13 | public static int getStatusBarHeight(Context context) { 14 | Resources resources = context.getResources(); 15 | int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android"); 16 | int height = resources.getDimensionPixelSize(resourceId); 17 | return height; 18 | } 19 | 20 | public static int changeAlpha(int color, float fraction) { 21 | int red = Color.red(color); 22 | int green = Color.green(color); 23 | int blue = Color.blue(color); 24 | int alpha = (int) (Color.alpha(color) * fraction); 25 | return Color.argb(alpha, red, green, blue); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_load_fragment.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 14 | 18 | 26 | 32 | 36 | 41 | 46 | 47 | 55 | 56 | 57 | 58 | 66 | 67 | 68 | 69 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 |