├── .gitignore ├── README-EN.md ├── README.md ├── build.gradle ├── config.gradle ├── example ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── dyhdyh │ │ └── loadingbar │ │ └── example │ │ ├── BaseActivity.java │ │ ├── DividerGridItemDecoration.java │ │ ├── ListLoadingActivity.java │ │ ├── MainActivity.java │ │ ├── SimpleAnimatorListener.java │ │ └── adapter │ │ ├── ExampleModel.java │ │ └── TextAdapter.java │ └── res │ ├── anim │ ├── alpha_enter.xml │ ├── alpha_exit.xml │ ├── scale_center_enter.xml │ └── scale_center_exit.xml │ ├── layout │ ├── activity_list_loading.xml │ ├── activity_loading_dialog.xml │ ├── activity_loadingbar.xml │ ├── activity_main.xml │ ├── item_text.xml │ ├── layout_custom.xml │ ├── layout_global_loading.xml │ └── layout_progressbar_horizontal.xml │ ├── menu │ └── menu.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── mipmap-xxxhdpi │ ├── ic_launcher.png │ └── ic_launcher_d.png │ ├── values-v21 │ └── styles.xml │ ├── values-zh │ └── strings.xml │ └── values │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── loadingbar ├── bintray.gradle ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── dyhdyh │ │ └── widget │ │ └── loadingbar2 │ │ ├── LoadingBar.java │ │ ├── LoadingBarPool.java │ │ ├── controller │ │ ├── ControllerHandler.java │ │ ├── LoadingController.java │ │ ├── LoadingDialogController.java │ │ └── LoadingViewController.java │ │ ├── factory │ │ ├── LoadingFactory.java │ │ ├── MaterialDialogFactory.java │ │ └── MaterialViewFactory.java │ │ └── strategy │ │ ├── CoverParentStrategy.java │ │ ├── ParentStrategy.java │ │ └── SimpleParentStrategy.java │ └── res │ ├── drawable │ └── loading_progressbar_vertical_material.xml │ ├── layout │ ├── dialog_material_loading.xml │ ├── loading_progressbar_vertical_material.xml │ └── view_material_loading.xml │ ├── values-v21 │ └── loading_styles.xml │ └── values │ ├── loading_colors.xml │ ├── loading_strings.xml │ └── loading_styles.xml ├── screenshots ├── download.png └── loadingbar.gif └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | .idea 3 | build 4 | *.iml 5 | local.properties 6 | -------------------------------------------------------------------------------- /README-EN.md: -------------------------------------------------------------------------------- 1 | # LoadingBar 2 | 3 | [中文文档](README.md) 4 | 5 | LoadingBar has been upgraded to `2.0`, [1.x](https://github.com/dengyuhan/LoadingBar/tree/1.x) cannot be migrated 2.0, [1.x](https://github.com/dengyuhan/LoadingBar/tree/1.x) will continue to maintain. 6 | 7 | ## Download Example 8 | 9 | 10 | ## Gralde Import 11 | ```java 12 | implementation 'com.dyhdyh.loadingbar2:loadingbar:2.0.1' 13 | ``` 14 | 15 | ## Simple Usage (default style) 16 | #### LoadingView 17 | ``` 18 | //show loading in the form of View. 19 | //the parent here needs to be an overlayable layout. If the layout is not overwriteable, will look up the hierarchy. 20 | //FrameLayout/RelativeLayout/ConstraintLayout/DrawerLayout/CoordinatorLayout/CardView 21 | LoadingBar.view(parent).show(); 22 | 23 | //to cancel correctly, have to is the same parent as show(). 24 | LoadingBar.view(parent).cancel(); 25 | ``` 26 | 27 | #### LoadingDialog 28 | ``` 29 | //show loading in the form of Dialog. 30 | //note that context cannot be used ApplicationContext here. 31 | LoadingBar.dialog(context).show(); 32 | 33 | //cancel dialog 34 | //to cancel correctly, have to is the same context as show(). 35 | LoadingBar.dialog(context).cancel(); 36 | ``` 37 | 38 | ## Advanced Usage 39 | #### LoadingView 40 | 41 | ``` 42 | LoadingBar.view(parent) 43 | //create a factory to change the style. 44 | //.setFactory(new CustomViewFactory()) 45 | //create a view to change the style. 46 | //.setFactoryFromView(view) 47 | //set the style using the layout ID. 48 | .setFactoryFromResource(R.layout.layout_custom) 49 | //carrying extra info. 50 | .extras(new Object[]{}) 51 | .show(); 52 | 53 | //create a factory to change the style. 54 | public class CustomViewFactory implements LoadingFactory { 55 | 56 | /** 57 | * Factory class identifier 58 | * If when calling show() multiple times before cancel(), will not call again onCreate() when key is the same. 59 | * @return 60 | */ 61 | @Override 62 | public String getKey() { 63 | return getClass().getName(); 64 | } 65 | 66 | @Override 67 | public View onCreate(ViewGroup parent) { 68 | //Here the view of return is the style of Loading 69 | return LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_custom, parent, false);; 70 | } 71 | 72 | @Override 73 | public void updateStatus(Object[] extras) { 74 | //Each call to show() will call back here, including the extras carried 75 | } 76 | } 77 | ``` 78 | 79 | #### LoadingDialog 80 | 81 | ``` 82 | LoadingBar.dialog(context) 83 | //create a factory to change the style. 84 | //.setFactory(new CustomDialogFactory()) 85 | //create a view to change the style. 86 | //.setFactoryFromView(view) 87 | //set the style using the layout ID. 88 | .setFactoryFromResource(R.layout.layout_custom) 89 | //carrying extra info. 90 | .extras(new Object[]{}) 91 | .show(); 92 | 93 | //create a factory to change the style. 94 | public class CustomDialogFactory implements LoadingFactory { 95 | /** 96 | * Factory class identifier 97 | * If when calling show() multiple times before cancel(), will not call again onCreate() when key is the same. 98 | * @return 99 | */ 100 | @Override 101 | public String getKey() { 102 | return getClass().getName(); 103 | } 104 | 105 | @Override 106 | public Dialog onCreate(Context params) { 107 | //Here the dialog of return is the style of Loading 108 | return new AlertDialog.Builder(params) 109 | .setView(R.layout.layout_custom) 110 | .setCancelable(false) 111 | .create(); 112 | } 113 | 114 | @Override 115 | public void updateStatus(Object[] extras) { 116 | //Each call to show() will call back here, including the extras carried 117 | } 118 | } 119 | ``` 120 | 121 | If it is a `Factory` created by anonymous inner class, `getKey()` needs to be customized to ensure that styles can be distinguished, For example, use `layoutId` to distinguish. 122 | 123 | ``` 124 | private LoadingFactory createViewFactoryFromResource(@LayoutRes int layoutId) { 125 | return new LoadingFactory() { 126 | 127 | @Override 128 | public String getKey() { 129 | return String.format(Locale.getDefault(), "ViewFactoryFromResource@%d", layoutId); 130 | } 131 | 132 | @Override 133 | public View onCreate(ViewGroup parent) { 134 | return LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false); 135 | } 136 | 137 | @Override 138 | public void updateStatus(Object[] extras) { 139 | 140 | } 141 | }; 142 | } 143 | ``` 144 | 145 | ## Other API 146 | #### ControllerHandler 147 | ``` 148 | //Use ControllerHandler to further customize 149 | //The following example demonstrates the replacement of the Parent lookup strategy for LoadingView. 150 | LoadingBar.view(loadingContainer) 151 | .setControllerHandler(new ControllerHandler() { 152 | @Override 153 | public void handle(LoadingController controller) { 154 | //Set the Parent lookup strategy 155 | if (controller instanceof LoadingViewController) { 156 | ((LoadingViewController) controller).setParentStrategy(new SimpleParentStrategy()); 157 | } 158 | } 159 | }).show(); 160 | ``` 161 | 162 | #### Manual Release 163 | When calling `cancel()`, the LoadingBar will be automatically released. If there is an abnormal cancel, you can call `release` to manually release it. 164 | 165 | ``` 166 | LoadingBar.release(); 167 | ``` 168 | 169 | You can check the number of resources that are not currently released by `getPoolCount`. 170 | ``` 171 | LoadingBar.getPoolCount(); 172 | ``` 173 | 174 | ## Screenshot 175 | 176 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LoadingBar 2 | 3 | [English Document](README-EN.md) 4 | 5 | LoadingBar已升级`2.0`,[1.x](https://github.com/dengyuhan/LoadingBar/tree/1.x)版本无法迁移2.0,但[1.x](https://github.com/dengyuhan/LoadingBar/tree/1.x)会持续维护 6 | 7 | ## 下载示例 8 | 9 | 10 | ## Gralde引入 11 | ```java 12 | implementation 'com.dyhdyh.loadingbar2:loadingbar:2.0.1' 13 | ``` 14 | 15 | ## 简单用法(默认样式) 16 | #### LoadingView 17 | ``` 18 | //以View的形式显示loading 19 | //这里的parent需要是可覆盖的布局,如果传的不是可覆盖的布局,会一直随着层级往上找 20 | //FrameLayout/RelativeLayout/ConstraintLayout/DrawerLayout/CoordinatorLayout/CardView 21 | LoadingBar.view(parent).show(); 22 | 23 | //需要跟show方法传的是同一个parent 才能正确取消 24 | LoadingBar.view(parent).cancel(); 25 | ``` 26 | 27 | #### LoadingDialog 28 | ``` 29 | //以Dialog的形式显示Loading 30 | //注意这里context不能用ApplicationContext 31 | LoadingBar.dialog(context).show(); 32 | 33 | //取消Dialog 34 | //需要跟show方法传的是同一个context 才能正确取消 35 | LoadingBar.dialog(context).cancel(); 36 | ``` 37 | 38 | ## 进阶用法 39 | #### LoadingView 40 | 41 | ``` 42 | LoadingBar.view(parent) 43 | //通过工厂设置样式 44 | //.setFactory(new CustomViewFactory()) 45 | //通过View设置样式 46 | //.setFactoryFromView(view) 47 | //通过布局ID设置样式 48 | .setFactoryFromResource(R.layout.layout_custom) 49 | //携带参数 50 | .extras(new Object[]{}) 51 | .show(); 52 | 53 | //通过工厂设置样式 54 | public class CustomViewFactory implements LoadingFactory { 55 | 56 | /** 57 | * 工厂类的标识符 58 | * 在cancel()之前多次调用show()时,当key相同时不会重新调用onCreate 59 | * @return 60 | */ 61 | @Override 62 | public String getKey() { 63 | return getClass().getName(); 64 | } 65 | 66 | @Override 67 | public View onCreate(ViewGroup parent) { 68 | //这里return的View就是Loading的样式 69 | return LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_custom, parent, false);; 70 | } 71 | 72 | @Override 73 | public void updateStatus(Object[] extras) { 74 | //每次调用show会回调这里 还有携带的参数 75 | } 76 | } 77 | ``` 78 | 79 | #### LoadingDialog 80 | 81 | ``` 82 | LoadingBar.dialog(context) 83 | //通过工厂设置样式 84 | //.setFactory(new CustomDialogFactory()) 85 | //通过View设置样式 86 | //.setFactoryFromView(view) 87 | //通过布局ID设置样式 88 | .setFactoryFromResource(R.layout.layout_custom) 89 | //携带参数 90 | .extras(new Object[]{}) 91 | .show(); 92 | 93 | //通过工厂设置样式 94 | public class CustomDialogFactory implements LoadingFactory { 95 | /** 96 | * 工厂类的标识符 97 | * 在cancel()之前多次调用show()时,当key相同时不会重新调用onCreate 98 | * @return 99 | */ 100 | @Override 101 | public String getKey() { 102 | return getClass().getName(); 103 | } 104 | 105 | @Override 106 | public Dialog onCreate(Context params) { 107 | //这里return的dialog就是Loading的样式 108 | return new AlertDialog.Builder(params) 109 | .setView(R.layout.layout_custom) 110 | .setCancelable(false) 111 | .create(); 112 | } 113 | 114 | @Override 115 | public void updateStatus(Object[] extras) { 116 | //每次调用show会回调这里 还有携带的参数 117 | } 118 | } 119 | ``` 120 | 121 | 如果是通过`匿名内部类`创建的`Factory`,`getKey()`需要自定义以保证可以区分样式,例如用`layoutId`区分 122 | 123 | ``` 124 | private LoadingFactory createViewFactoryFromResource(@LayoutRes int layoutId) { 125 | return new LoadingFactory() { 126 | 127 | @Override 128 | public String getKey() { 129 | return String.format(Locale.getDefault(), "ViewFactoryFromResource@%d", layoutId); 130 | } 131 | 132 | @Override 133 | public View onCreate(ViewGroup parent) { 134 | return LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false); 135 | } 136 | 137 | @Override 138 | public void updateStatus(Object[] extras) { 139 | 140 | } 141 | }; 142 | } 143 | ``` 144 | 145 | ## 其它API 146 | #### ControllerHandler 147 | ``` 148 | //使用ControllerHandler可以更进一步定制 149 | //下面的例子演示了 更换LoadingView的Parent查找策略 150 | LoadingBar.view(loadingContainer) 151 | .setControllerHandler(new ControllerHandler() { 152 | @Override 153 | public void handle(LoadingController controller) { 154 | //调整Parent查找策略 155 | if (controller instanceof LoadingViewController) { 156 | ((LoadingViewController) controller).setParentStrategy(new SimpleParentStrategy()); 157 | } 158 | } 159 | }).show(); 160 | ``` 161 | 162 | #### 手动释放 163 | 当调用`cancel()`的时候,LoadingBar会自动释放,如果有不正常cancel的情况,可以调用`release`手动释放。 164 | 165 | ``` 166 | LoadingBar.release(); 167 | ``` 168 | 169 | 可以通过`getPoolCount`查看当前没有释放的资源数量。 170 | ``` 171 | LoadingBar.getPoolCount(); 172 | ``` 173 | 174 | 175 | 176 | ## 截图 177 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | apply from: "config.gradle" 2 | buildscript { 3 | 4 | repositories { 5 | jcenter() 6 | google() 7 | } 8 | 9 | dependencies { 10 | classpath 'com.android.tools.build:gradle:3.0.0' 11 | 12 | classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3' 13 | classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5' 14 | 15 | // NOTE: Do not place your application dependencies here; they belong 16 | // in the individual module build.gradle files 17 | } 18 | } 19 | 20 | allprojects { 21 | repositories { 22 | jcenter() 23 | google() 24 | } 25 | } 26 | 27 | task clean(type: Delete) { 28 | delete rootProject.buildDir 29 | } 30 | -------------------------------------------------------------------------------- /config.gradle: -------------------------------------------------------------------------------- 1 | ext { 2 | android = 3 | [ 4 | applicationId : "com.dyhdyh.loadingbar.example", 5 | 6 | //版本号 7 | versionCode : 10, 8 | versionName : "2.0.1", 9 | 10 | //sdk版本 11 | compileSdkVersion: 28, 12 | buildToolsVersion: "28.0.3", 13 | minSdkVersion : 14, 14 | targetSdkVersion : 28, 15 | supportVersion : "28.0.0", 16 | ] 17 | 18 | jcenter = 19 | [ 20 | //项目名称 21 | name : "LoadingBar2", 22 | groupId : "com.dyhdyh.loadingbar2", 23 | //项目地址 24 | siteUrl : "https://github.com/dengyuhan/LoadingBar", 25 | //项目git地址 26 | gitUrl : "https://github.com/dengyuhan/LoadingBar.git", 27 | //项目描述 28 | description: "极简使用的解耦Loading组件 - http://blog.csdn.net/aa464971/article/details/70197394", 29 | //开发者的一些基本信息 30 | authorId : "dengyuhan", 31 | authorName : "dengyuhan", 32 | authorEmail: "22309946@qq.com", 33 | 34 | //开源协议 35 | licenses : { 36 | license { 37 | name 'Apache-2.0' 38 | url 'https://opensource.org/licenses/Apache-2.0' 39 | } 40 | }, 41 | licenseName: 'Apache-2.0' 42 | ] 43 | 44 | 45 | } 46 | -------------------------------------------------------------------------------- /example/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion rootProject.ext.android.compileSdkVersion 5 | buildToolsVersion rootProject.ext.android.buildToolsVersion 6 | defaultConfig { 7 | applicationId rootProject.ext.android.applicationId 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 | dependencies { 23 | implementation fileTree(dir: 'libs', include: ['*.jar']) 24 | implementation "com.android.support:appcompat-v7:$rootProject.ext.android.supportVersion" 25 | implementation "com.android.support:design:$rootProject.ext.android.supportVersion" 26 | implementation project(':loadingbar') 27 | implementation 'com.wang.avi:library:2.1.3' 28 | } -------------------------------------------------------------------------------- /example/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in D:\dev\android-sdk-windows/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 | -------------------------------------------------------------------------------- /example/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /example/src/main/java/com/dyhdyh/loadingbar/example/BaseActivity.java: -------------------------------------------------------------------------------- 1 | package com.dyhdyh.loadingbar.example; 2 | 3 | import android.os.Build; 4 | import android.support.v7.app.AppCompatActivity; 5 | 6 | /** 7 | * author dengyuhan 8 | * created 2017/4/16 15:35 9 | */ 10 | public class BaseActivity extends AppCompatActivity { 11 | 12 | @Override 13 | protected void onTitleChanged(CharSequence title, int color) { 14 | super.onTitleChanged(title + " - Android " + Build.VERSION.RELEASE, color); 15 | } 16 | 17 | @Override 18 | protected void onDestroy() { 19 | super.onDestroy(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /example/src/main/java/com/dyhdyh/loadingbar/example/DividerGridItemDecoration.java: -------------------------------------------------------------------------------- 1 | package com.dyhdyh.loadingbar.example; 2 | 3 | import android.content.Context; 4 | import android.content.res.TypedArray; 5 | import android.graphics.Canvas; 6 | import android.graphics.Rect; 7 | import android.graphics.drawable.Drawable; 8 | import android.support.v7.widget.GridLayoutManager; 9 | import android.support.v7.widget.RecyclerView; 10 | import android.support.v7.widget.StaggeredGridLayoutManager; 11 | import android.view.View; 12 | 13 | /** 14 | * author dengyuhan 15 | * created 2017/4/16 02:36 16 | */ 17 | public class DividerGridItemDecoration extends RecyclerView.ItemDecoration 18 | { 19 | 20 | private static final int[] ATTRS = new int[] { android.R.attr.listDivider }; 21 | private Drawable mDivider; 22 | 23 | public DividerGridItemDecoration(Context context) 24 | { 25 | final TypedArray a = context.obtainStyledAttributes(ATTRS); 26 | mDivider = a.getDrawable(0); 27 | a.recycle(); 28 | } 29 | 30 | @Override 31 | public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) 32 | { 33 | 34 | drawHorizontal(c, parent); 35 | drawVertical(c, parent); 36 | 37 | } 38 | 39 | private int getSpanCount(RecyclerView parent) 40 | { 41 | // 列数 42 | int spanCount = -1; 43 | RecyclerView.LayoutManager layoutManager = parent.getLayoutManager(); 44 | if (layoutManager instanceof GridLayoutManager) 45 | { 46 | 47 | spanCount = ((GridLayoutManager) layoutManager).getSpanCount(); 48 | } else if (layoutManager instanceof StaggeredGridLayoutManager) 49 | { 50 | spanCount = ((StaggeredGridLayoutManager) layoutManager) 51 | .getSpanCount(); 52 | } 53 | return spanCount; 54 | } 55 | 56 | public void drawHorizontal(Canvas c, RecyclerView parent) 57 | { 58 | int childCount = parent.getChildCount(); 59 | for (int i = 0; i < childCount; i++) 60 | { 61 | final View child = parent.getChildAt(i); 62 | final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child 63 | .getLayoutParams(); 64 | final int left = child.getLeft() - params.leftMargin; 65 | final int right = child.getRight() + params.rightMargin 66 | + mDivider.getIntrinsicWidth(); 67 | final int top = child.getBottom() + params.bottomMargin; 68 | final int bottom = top + mDivider.getIntrinsicHeight(); 69 | mDivider.setBounds(left, top, right, bottom); 70 | mDivider.draw(c); 71 | } 72 | } 73 | 74 | public void drawVertical(Canvas c, RecyclerView parent) 75 | { 76 | final int childCount = parent.getChildCount(); 77 | for (int i = 0; i < childCount; i++) 78 | { 79 | final View child = parent.getChildAt(i); 80 | 81 | final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child 82 | .getLayoutParams(); 83 | final int top = child.getTop() - params.topMargin; 84 | final int bottom = child.getBottom() + params.bottomMargin; 85 | final int left = child.getRight() + params.rightMargin; 86 | final int right = left + mDivider.getIntrinsicWidth(); 87 | 88 | mDivider.setBounds(left, top, right, bottom); 89 | mDivider.draw(c); 90 | } 91 | } 92 | 93 | private boolean isLastColum(RecyclerView parent, int pos, int spanCount, 94 | int childCount) 95 | { 96 | RecyclerView.LayoutManager layoutManager = parent.getLayoutManager(); 97 | if (layoutManager instanceof GridLayoutManager) 98 | { 99 | if ((pos + 1) % spanCount == 0)// 如果是最后一列,则不需要绘制右边 100 | { 101 | return true; 102 | } 103 | } else if (layoutManager instanceof StaggeredGridLayoutManager) 104 | { 105 | int orientation = ((StaggeredGridLayoutManager) layoutManager) 106 | .getOrientation(); 107 | if (orientation == StaggeredGridLayoutManager.VERTICAL) 108 | { 109 | if ((pos + 1) % spanCount == 0)// 如果是最后一列,则不需要绘制右边 110 | { 111 | return true; 112 | } 113 | } else 114 | { 115 | childCount = childCount - childCount % spanCount; 116 | if (pos >= childCount)// 如果是最后一列,则不需要绘制右边 117 | return true; 118 | } 119 | } 120 | return false; 121 | } 122 | 123 | private boolean isLastRaw(RecyclerView parent, int pos, int spanCount, 124 | int childCount) 125 | { 126 | RecyclerView.LayoutManager layoutManager = parent.getLayoutManager(); 127 | if (layoutManager instanceof GridLayoutManager) 128 | { 129 | childCount = childCount - childCount % spanCount; 130 | if (pos >= childCount)// 如果是最后一行,则不需要绘制底部 131 | return true; 132 | } else if (layoutManager instanceof StaggeredGridLayoutManager) 133 | { 134 | int orientation = ((StaggeredGridLayoutManager) layoutManager) 135 | .getOrientation(); 136 | // StaggeredGridLayoutManager 且纵向滚动 137 | if (orientation == StaggeredGridLayoutManager.VERTICAL) 138 | { 139 | childCount = childCount - childCount % spanCount; 140 | // 如果是最后一行,则不需要绘制底部 141 | if (pos >= childCount) 142 | return true; 143 | } else 144 | // StaggeredGridLayoutManager 且横向滚动 145 | { 146 | // 如果是最后一行,则不需要绘制底部 147 | if ((pos + 1) % spanCount == 0) 148 | { 149 | return true; 150 | } 151 | } 152 | } 153 | return false; 154 | } 155 | 156 | @Override 157 | public void getItemOffsets(Rect outRect, int itemPosition, 158 | RecyclerView parent) 159 | { 160 | int spanCount = getSpanCount(parent); 161 | int childCount = parent.getAdapter().getItemCount(); 162 | if (isLastRaw(parent, itemPosition, spanCount, childCount))// 如果是最后一行,则不需要绘制底部 163 | { 164 | outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0); 165 | } else if (isLastColum(parent, itemPosition, spanCount, childCount))// 如果是最后一列,则不需要绘制右边 166 | { 167 | outRect.set(0, 0, 0, mDivider.getIntrinsicHeight()); 168 | } else 169 | { 170 | outRect.set(0, 0, mDivider.getIntrinsicWidth(), 171 | mDivider.getIntrinsicHeight()); 172 | } 173 | } 174 | } -------------------------------------------------------------------------------- /example/src/main/java/com/dyhdyh/loadingbar/example/ListLoadingActivity.java: -------------------------------------------------------------------------------- 1 | package com.dyhdyh.loadingbar.example; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.widget.GridLayoutManager; 5 | import android.support.v7.widget.RecyclerView; 6 | 7 | import com.dyhdyh.loadingbar.example.adapter.ExampleModel; 8 | import com.dyhdyh.loadingbar.example.adapter.TextAdapter; 9 | 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | import java.util.Random; 13 | 14 | /** 15 | * 多loading的操作 16 | * author dengyuhan 17 | * created 2016/7/27 18:29 18 | */ 19 | public class ListLoadingActivity extends BaseActivity { 20 | private RecyclerView rv; 21 | 22 | @Override 23 | protected void onCreate(Bundle savedInstanceState) { 24 | super.onCreate(savedInstanceState); 25 | setContentView(R.layout.activity_list_loading); 26 | rv = this.findViewById(R.id.rv); 27 | 28 | rv.setLayoutManager(new GridLayoutManager(this,3)); 29 | rv.addItemDecoration(new DividerGridItemDecoration(this)); 30 | rv.setAdapter(new TextAdapter(getTestData())); 31 | } 32 | 33 | private List getTestData() { 34 | List data = new ArrayList<>(); 35 | for (int i = 0; i < 40; i++) { 36 | data.add(new ExampleModel("Item " + i,true,new Random().nextInt(2000))); 37 | } 38 | return data; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /example/src/main/java/com/dyhdyh/loadingbar/example/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.dyhdyh.loadingbar.example; 2 | 3 | import android.animation.Animator; 4 | import android.animation.ValueAnimator; 5 | import android.content.Intent; 6 | import android.os.Bundle; 7 | import android.view.Menu; 8 | import android.view.MenuItem; 9 | import android.view.View; 10 | import android.widget.TextView; 11 | 12 | import com.dyhdyh.widget.loadingbar2.LoadingBar; 13 | 14 | import java.util.Timer; 15 | import java.util.TimerTask; 16 | 17 | public class MainActivity extends BaseActivity { 18 | View loadingContainer; 19 | TextView tv_pool_count; 20 | 21 | @Override 22 | protected void onCreate(Bundle savedInstanceState) { 23 | super.onCreate(savedInstanceState); 24 | setContentView(R.layout.activity_main); 25 | 26 | loadingContainer = findViewById(R.id.layout_loading_container); 27 | tv_pool_count = findViewById(R.id.tv_pool_count); 28 | 29 | startRefreshPoolCountTimer(); 30 | } 31 | 32 | public void clickShowView(View view) { 33 | LoadingBar.view(loadingContainer).show(); 34 | } 35 | 36 | public void clickCancelView(View view) { 37 | LoadingBar.view(loadingContainer).cancel(); 38 | } 39 | 40 | public void clickShowViewExtras(View view) { 41 | final ValueAnimator animator = ValueAnimator.ofInt(0, 100).setDuration(2000); 42 | animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 43 | @Override 44 | public void onAnimationUpdate(ValueAnimator animation) { 45 | final int value = (int) animation.getAnimatedValue(); 46 | 47 | //显示view 并携带参数 48 | LoadingBar.view(loadingContainer).extras(new Object[]{value + "%"}).show(); 49 | } 50 | }); 51 | animator.addListener(new SimpleAnimatorListener() { 52 | 53 | @Override 54 | public void onAnimationEnd(Animator animation) { 55 | //取消view 56 | LoadingBar.view(loadingContainer).cancel(); 57 | } 58 | }); 59 | animator.start(); 60 | } 61 | 62 | public void clickCustomView(View view) { 63 | LoadingBar.view(loadingContainer) 64 | //.setFactory() 65 | .setFactoryFromView(view) 66 | .setFactoryFromResource(R.layout.layout_custom) 67 | .show(); 68 | } 69 | 70 | public void clickShowDialog(View view) { 71 | //显示dialog 72 | LoadingBar.dialog(MainActivity.this).show(); 73 | final ValueAnimator animator = ValueAnimator.ofInt(0, 100).setDuration(2000); 74 | animator.addListener(new SimpleAnimatorListener() { 75 | 76 | @Override 77 | public void onAnimationEnd(Animator animation) { 78 | //取消dialog 79 | LoadingBar.dialog(MainActivity.this).cancel(); 80 | } 81 | }); 82 | animator.start(); 83 | } 84 | 85 | public void clickShowDialogExtras(View view) { 86 | final ValueAnimator animator = ValueAnimator.ofInt(0, 100).setDuration(2000); 87 | animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 88 | @Override 89 | public void onAnimationUpdate(ValueAnimator animation) { 90 | final int value = (int) animation.getAnimatedValue(); 91 | 92 | //显示dialog 并携带参数 93 | LoadingBar.dialog(MainActivity.this).extras(new Object[]{value + "%"}).show(); 94 | } 95 | }); 96 | animator.addListener(new SimpleAnimatorListener() { 97 | 98 | @Override 99 | public void onAnimationEnd(Animator animation) { 100 | //取消dialog 101 | LoadingBar.dialog(MainActivity.this).cancel(); 102 | } 103 | }); 104 | animator.start(); 105 | } 106 | 107 | public void clickCustomDialog(View view) { 108 | LoadingBar.dialog(MainActivity.this).setFactoryFromResource(R.layout.layout_custom).show(); 109 | final ValueAnimator animator = ValueAnimator.ofInt(0, 100).setDuration(2000); 110 | animator.addListener(new SimpleAnimatorListener() { 111 | 112 | @Override 113 | public void onAnimationEnd(Animator animation) { 114 | //取消dialog 115 | LoadingBar.dialog(MainActivity.this).cancel(); 116 | } 117 | }); 118 | animator.start(); 119 | } 120 | 121 | public void clickRecycling(MenuItem item) { 122 | LoadingBar.release(); 123 | } 124 | 125 | public void clickListLoading(MenuItem item) { 126 | startActivity(new Intent(this, ListLoadingActivity.class)); 127 | } 128 | 129 | @Override 130 | public boolean onCreateOptionsMenu(Menu menu) { 131 | getMenuInflater().inflate(R.menu.menu, menu); 132 | return super.onCreateOptionsMenu(menu); 133 | } 134 | 135 | 136 | /** 137 | * 刷新池的数量 138 | */ 139 | private Timer mTimer; 140 | 141 | private void startRefreshPoolCountTimer() { 142 | mTimer = new Timer(); 143 | mTimer.schedule(new TimerTask() { 144 | @Override 145 | public void run() { 146 | runOnUiThread(new Runnable() { 147 | @Override 148 | public void run() { 149 | tv_pool_count.setText(String.valueOf(LoadingBar.getPoolCount())); 150 | } 151 | }); 152 | } 153 | }, 0, 500); 154 | } 155 | 156 | @Override 157 | public void finish() { 158 | super.finish(); 159 | mTimer.cancel(); 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /example/src/main/java/com/dyhdyh/loadingbar/example/SimpleAnimatorListener.java: -------------------------------------------------------------------------------- 1 | package com.dyhdyh.loadingbar.example; 2 | 3 | import android.animation.Animator; 4 | 5 | /** 6 | * @author dengyuhan 7 | * created 2019/3/14 16:59 8 | */ 9 | public class SimpleAnimatorListener implements Animator.AnimatorListener { 10 | @Override 11 | public void onAnimationStart(Animator animation) { 12 | 13 | } 14 | 15 | @Override 16 | public void onAnimationEnd(Animator animation) { 17 | 18 | } 19 | 20 | @Override 21 | public void onAnimationCancel(Animator animation) { 22 | 23 | } 24 | 25 | @Override 26 | public void onAnimationRepeat(Animator animation) { 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /example/src/main/java/com/dyhdyh/loadingbar/example/adapter/ExampleModel.java: -------------------------------------------------------------------------------- 1 | package com.dyhdyh.loadingbar.example.adapter; 2 | 3 | /** 4 | * author dengyuhan 5 | * created 2017/4/16 14:27 6 | */ 7 | public class ExampleModel { 8 | private String text; 9 | private boolean show; 10 | private int duration; 11 | 12 | public ExampleModel(String text, boolean show, int duration) { 13 | this.text = text; 14 | this.show = show; 15 | this.duration = duration; 16 | } 17 | 18 | public int getDuration() { 19 | return duration; 20 | } 21 | 22 | public void setDuration(int duration) { 23 | this.duration = duration; 24 | } 25 | 26 | public String getText() { 27 | return text; 28 | } 29 | 30 | public void setText(String text) { 31 | this.text = text; 32 | } 33 | 34 | public boolean isShow() { 35 | return show; 36 | } 37 | 38 | public void setShow(boolean show) { 39 | this.show = show; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /example/src/main/java/com/dyhdyh/loadingbar/example/adapter/TextAdapter.java: -------------------------------------------------------------------------------- 1 | package com.dyhdyh.loadingbar.example.adapter; 2 | 3 | import android.os.Handler; 4 | import android.support.v7.widget.RecyclerView; 5 | import android.view.LayoutInflater; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.widget.TextView; 9 | 10 | import com.dyhdyh.loadingbar.example.R; 11 | import com.dyhdyh.widget.loadingbar2.LoadingBar; 12 | 13 | import java.util.List; 14 | 15 | 16 | /** 17 | * author dengyuhan 18 | * created 2017/4/16 02:18 19 | */ 20 | public class TextAdapter extends RecyclerView.Adapter { 21 | private List mData; 22 | private Handler mHandler = new Handler(); 23 | 24 | public TextAdapter(List data) { 25 | this.mData = data; 26 | } 27 | 28 | @Override 29 | public Holder onCreateViewHolder(ViewGroup parent, int viewType) { 30 | return new Holder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_text, parent, false)); 31 | } 32 | 33 | @Override 34 | public void onBindViewHolder(final Holder holder, int position) { 35 | final ExampleModel model = mData.get(position); 36 | holder.tv.setText(model.getText()); 37 | if (model.isShow()) { 38 | LoadingBar.view(holder.itemView).show(); 39 | 40 | mHandler.postDelayed(new Runnable() { 41 | @Override 42 | public void run() { 43 | model.setShow(false); 44 | LoadingBar.view(holder.itemView).cancel(); 45 | } 46 | }, model.getDuration()); 47 | } else { 48 | LoadingBar.view(holder.itemView).cancel(); 49 | } 50 | } 51 | 52 | @Override 53 | public int getItemCount() { 54 | return mData.size(); 55 | } 56 | 57 | static class Holder extends RecyclerView.ViewHolder { 58 | TextView tv; 59 | 60 | public Holder(View itemView) { 61 | super(itemView); 62 | 63 | tv = (TextView) itemView.findViewById(R.id.tv); 64 | } 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /example/src/main/res/anim/alpha_enter.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | -------------------------------------------------------------------------------- /example/src/main/res/anim/alpha_exit.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | -------------------------------------------------------------------------------- /example/src/main/res/anim/scale_center_enter.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 13 | 16 | -------------------------------------------------------------------------------- /example/src/main/res/anim/scale_center_exit.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 13 | 16 | -------------------------------------------------------------------------------- /example/src/main/res/layout/activity_list_loading.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 15 | -------------------------------------------------------------------------------- /example/src/main/res/layout/activity_loading_dialog.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 12 | 13 | 17 | 18 | 24 | 25 | 26 | 27 | 33 | 34 |