├── .gitignore
├── .idea
├── caches
│ └── build_file_checksums.ser
├── compiler.xml
├── copyright
│ └── profiles_settings.xml
├── encodings.xml
├── gradle.xml
├── markdown-navigator.xml
├── markdown-navigator
│ └── profiles_settings.xml
├── misc.xml
├── modules.xml
├── runConfigurations.xml
└── vcs.xml
├── README-cn.md
├── README.md
├── UpdateLog.md
├── app-debug.apk
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── zone
│ │ │ └── com
│ │ │ └── zrefreshlayoutdemo
│ │ │ ├── Apps.kt
│ │ │ ├── AutoRefreshActivity.kt
│ │ │ ├── CircleHeaderActivity.kt
│ │ │ ├── CirlcleActivity.kt
│ │ │ ├── FlexibilityKtActivity.kt
│ │ │ ├── GlobalViewActivity.java
│ │ │ ├── GridViewActivity.kt
│ │ │ ├── ListViewActivity.kt
│ │ │ ├── MainActivity.kt
│ │ │ ├── MeterialHeaderActivity.kt
│ │ │ ├── PinContentActivity.kt
│ │ │ ├── RecyclerViewActivity.kt
│ │ │ ├── RefreshPositionActivity.kt
│ │ │ ├── ResistanceActivity.kt
│ │ │ ├── SPManager.kt
│ │ │ ├── ScrollerNesttActivity.kt
│ │ │ ├── ScrollerViewActivity.kt
│ │ │ ├── SettingActivity.kt
│ │ │ ├── SinaHeaderActivity.kt
│ │ │ ├── TextViewActivity.java
│ │ │ ├── UniqueFeatureActivity.kt
│ │ │ ├── WaveHeaderActivity.kt
│ │ │ ├── WebViewActivity.kt
│ │ │ ├── common
│ │ │ ├── Constant.kt
│ │ │ └── HeadSetting.kt
│ │ │ ├── delegate
│ │ │ ├── AdapterList.kt
│ │ │ └── MenuEntityDeletates.kt
│ │ │ ├── header
│ │ │ ├── CircleRefresh.java
│ │ │ ├── SinaRefreshViewRefreshPositionTest.java
│ │ │ ├── WaveHead.java
│ │ │ └── view
│ │ │ │ └── AnimationView.java
│ │ │ ├── resistance
│ │ │ └── Damping2Head8per.kt
│ │ │ └── utils
│ │ │ └── RecyclerViewEmptyUtils.java
│ └── res
│ │ ├── drawable-xxhdpi
│ │ ├── aaaaaaaaaaaab.jpg
│ │ ├── img_header.png
│ │ └── wave.png
│ │ ├── layout
│ │ ├── a_circle.xml
│ │ ├── a_flexibility.xml
│ │ ├── a_scroll_recycler_nest.xml
│ │ ├── a_setting.xml
│ │ ├── auto_refresh.xml
│ │ ├── grid.xml
│ │ ├── item_menu.xml
│ │ ├── item_rc_textview.xml
│ │ ├── list.xml
│ │ ├── main.xml
│ │ ├── rev.xml
│ │ ├── scroller.xml
│ │ ├── text.xml
│ │ ├── title.xml
│ │ ├── unique_feature.xml
│ │ ├── unique_feature_copy.xml
│ │ └── web.xml
│ │ ├── mipmap-hdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-mdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xhdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xxhdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xxxhdpi
│ │ └── ic_launcher.png
│ │ ├── values-w820dp
│ │ └── dimens.xml
│ │ ├── values
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ │ └── xml
│ │ └── network_security_config.xml
│ └── test
│ └── java
│ └── zone
│ └── com
│ └── zrefreshlayoutdemo
│ └── ExampleUnitTest.java
├── build.gradle
├── demo
└── home.png
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── zrefreshlayout
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
├── androidTest
└── java
│ └── zone
│ └── com
│ └── zrefreshlayoutdemo
│ └── ExampleInstrumentedTest.java
├── main
├── AndroidManifest.xml
├── java
│ └── zone
│ │ └── com
│ │ └── zrefreshlayout
│ │ ├── AUtils.kt
│ │ ├── Config.java
│ │ ├── FlexibilityLayout.kt
│ │ ├── IFooterView.java
│ │ ├── IHeaderView.java
│ │ ├── IResistance.java
│ │ ├── IScroll.java
│ │ ├── NestFrameLayout.java
│ │ ├── ScrollAnimation.java
│ │ ├── ZRefreshLayout.java
│ │ ├── footer
│ │ ├── LoadFooter.java
│ │ ├── MeterialFooter.java
│ │ └── NullFooter.java
│ │ ├── header
│ │ ├── MeterialHead.java
│ │ ├── NullHeader.kt
│ │ └── SinaRefreshHeader.java
│ │ ├── loadmore
│ │ ├── ListViewLoadMoreListener.java
│ │ ├── LoadMoreController.java
│ │ ├── LoadMoreOtherListener.java
│ │ └── RecyclerViewLoadMoreListener.java
│ │ ├── resistance
│ │ ├── DampingHalf.java
│ │ ├── DampingHalfToHead.java
│ │ └── DampingTo3Head.java
│ │ ├── scroll
│ │ ├── ScrollDoNothing.kt
│ │ ├── ScrollPin.kt
│ │ ├── ScrollPinNot.kt
│ │ └── listener
│ │ │ ├── ScrollScale.kt
│ │ │ └── ScrollScroll.kt
│ │ ├── utils
│ │ ├── DensityUtils.java
│ │ ├── LogUtils.java
│ │ ├── RecyclerViewUtils.java
│ │ ├── ScreenUtils.java
│ │ ├── ScrollingUtil.java
│ │ └── SimpleAnimatorListener.java
│ │ └── v4
│ │ ├── CircleImageView.java
│ │ ├── MaterialProgressDrawable.java
│ │ └── MeterialCircle.java
└── res
│ ├── drawable-xxhdpi
│ ├── ic_arrow.png
│ └── refresh_loading01.png
│ ├── layout
│ ├── footer.xml
│ ├── header.xml
│ ├── header_meterial.xml
│ └── view_sinaheader.xml
│ └── values
│ └── strings.xml
└── test
└── java
└── zone
└── com
└── zrefreshlayoutdemo
└── ExampleUnitTest.java
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 | .externalNativeBuild
10 |
--------------------------------------------------------------------------------
/.idea/caches/build_file_checksums.ser:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luhaoaimama1/ZRefreshLayout/1226a2d020b718687865b369810d069328e547cb/.idea/caches/build_file_checksums.ser
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
18 |
19 |
--------------------------------------------------------------------------------
/.idea/markdown-navigator.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/.idea/markdown-navigator/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | Android
36 |
37 |
38 | Android > Lint > Correctness
39 |
40 |
41 | Java
42 |
43 |
44 | Java language level migration aidsJava
45 |
46 |
47 |
48 |
49 | AndroidLintNewerVersionAvailable
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 | 1.8
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/README-cn.md:
--------------------------------------------------------------------------------
1 | # ZRefreshLayout
2 |
3 | 一个可以`全局`随意`配置头部`的`下拉刷新`与`上拉加载`库;
4 |
5 | ### 特点与功能实现
6 | - [x] 支持添加下拉刷新与上拉加载
7 | - [x] 支持超时而自动做出刷新或者加载完成动作
8 | - [x] 支持嵌套滑动
9 | - [x] 支持所有的View:ImageView,FrameLayout,ListView, GridView, ScrollView, WebView...
10 | - [x] 全局配置(头部配置都在这里,所以没有xml属性~),与独立更改
11 | - [x] 自动刷新
12 | - [x] 头部是否固定
13 | - [x] 刷新出发位置
14 | - [x] 下拉位置映射,既resistance阻力
15 | - [x] 因为是继承FrameLayout,可以添加多个child。(我没有让控制必须一个,感觉更灵活吧)
16 |
17 | ### JicPack
18 | Add it in your root build.gradle at the end of repositories:
19 | ```
20 | allprojects {
21 | repositories {
22 | ...
23 | maven { url "https://jitpack.io" }
24 | }
25 | }
26 | ```
27 | Step 2. Add the dependency
28 |
29 | > compile 'com.github.luhaoaimama1:ZRefreshLayout:[Latest release](https://github.com/luhaoaimama1/ZRefreshLayout/releases)'
30 | > 非 anroidX 版本使用 compile 'com.github.luhaoaimama1:ZRefreshLayout:1.0.19' 分支:notAndroidx
31 |
32 | Step 3. Step 3: you need provide
33 |
34 | 原因: compileOnly 'androidx.recyclerview:recyclerview:1.0.0'
35 |
36 | ## UML
37 |
38 | 
39 |
40 | ## Preview
41 |
42 | #### 固定头
43 | 
44 |
45 | #### Meterial Header与Footer
46 | 
47 |
48 | #### SinaRefreshHeader与LoadFooter
49 | 
50 |
51 | #### WaveHead
52 | 
53 |
54 | #### CircleRefresh Head
55 | >[引用tuesda的CircleView 主要是为了测试延迟功能](https://github.com/tuesda/CircleRefreshLayout)
56 |
57 | 
58 |
59 | ## Usage
60 |
61 | #### 全局配置
62 |
63 | ```
64 | Config.build()
65 | .setHeader(new MeterialHead())
66 | .setFooter(new MeterialFooter())
67 | .setResistance(new Damping())
68 | .writeLog(true)
69 | .perform();
70 | ```
71 | #### 独立更改
72 |
73 | ```
74 | refresh.setIHeaderView(new SinaRefreshHeader());
75 | ```
76 |
77 | #### 头部固定否
78 |
79 | ```
80 | refresh.setHeadPin(ZRefreshLayout.HeadPin.PIN)
81 | ```
82 |
83 | #### 自动刷新
84 |
85 | ```
86 | refresh.autoRefresh(haveAnimate)
87 | ```
88 |
89 | ### 下拉监听
90 | > 刷新完成记得使用:**zRefreshLayout.refreshComplete();**
91 |
92 | ```
93 | refresh.setPullListener(new ZRefreshLayout.PullListener() {
94 | @Override
95 | public void refresh(final ZRefreshLayout zRefreshLayout) {
96 | tv.postDelayed(new Runnable() {
97 | @Override
98 | public void run() {
99 | tv.setText("刷新完毕:" + i++);
100 | zRefreshLayout.refreshComplete();
101 | }
102 | }, 500);
103 | }
104 | });
105 | ```
106 |
107 | #### 上拉监听
108 | > 如果没有设置上啦监听则不会有上拉加载功能
109 |
110 | > 加载完成记得使用:**zRefreshLayout.loadMoreComplete();**
111 |
112 | ```
113 | refresh.setPullListener(new ZRefreshLayout.PullListener() {
114 | @Override
115 | public void refresh(final ZRefreshLayout zRefreshLayout) {
116 | tv.postDelayed(new Runnable() {
117 | @Override
118 | public void run() {
119 | tv.setText("刷新完毕:" + i++);
120 | zRefreshLayout.refreshComplete();
121 | }
122 | }, 500);
123 | }
124 | });
125 | ```
126 |
127 | >头部自定义与底部自定义和更多高级功能,请看[**Wiki 文档**](https://github.com/luhaoaimama1/ZRefreshLayout/wiki);
128 |
129 | # Reference&Thanks:
130 |
131 | https://github.com/lcodecorex/TwinklingRefreshLayout
132 |
133 | https://github.com/tuesda/CircleRefreshLayout
134 |
135 | https://github.com/android-cjj/Android-MaterialRefreshLayout
136 |
137 | https://github.com/desmond1121/Android-Ptr-Comparison
138 |
139 | https://github.com/liaohuqiu/android-Ultra-Pull-To-Refresh
140 |
141 |
142 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | [中文版文档](README-cn.md)
3 |
4 | # ZRefreshLayout
5 |
6 | A global random configuration head , drop-down refresh and loadMore library;
7 |
8 | ## Feature
9 | - [x] support refresh and loadMore
10 | - [x] support Timeout automatically complete the action
11 | - [x] support nest scroll
12 | - [x] support All the View:ImageView,FrameLayout,ListView, GridView, ScrollView, WebView...
13 | - [x] support Global configuration (HeaderView's configuration is here,so not have xml's property),and Independent changes
14 | - [x] support auto refresh
15 | - [x] support header fixed
16 | - [x] support refresh's Trigger position
17 | - [x] support drop-down's position map(as IResistance)
18 | - [x] support add many childs。because extends FrameLayout(not must be one,because more changeful)
19 |
20 | ## JicPack
21 | Add it in your root build.gradle at the end of repositories:
22 | ```
23 | allprojects {
24 | repositories {
25 | ...
26 | maven { url "https://jitpack.io" }
27 | }
28 | }
29 | ```
30 | Step 2. Add the dependency
31 |
32 | > compile 'com.github.luhaoaimama1:ZRefreshLayout:[Latest release](https://github.com/luhaoaimama1/ZRefreshLayout/releases)'
33 |
34 | > not anroidX version compile 'com.github.luhaoaimama1:ZRefreshLayout:1.0.19' branch:notAndroidx
35 |
36 | Step 3: you need provide
37 |
38 | because compileOnly 'androidx.recyclerview:recyclerview:1.0.0'
39 |
40 |
41 |
42 | ## UML
43 |
44 | 
45 |
46 | ## Preview
47 |
48 | #### header fixed
49 | 
50 |
51 | #### Meterial Header与Footer
52 | 
53 |
54 | #### SinaRefreshHeader与LoadFooter
55 | 
56 |
57 | #### WaveHead
58 | 
59 |
60 | #### CircleRefresh Head
61 | >[引用tuesda的CircleView 主要是为了测试延迟功能](https://github.com/tuesda/CircleRefreshLayout)
62 |
63 | 
64 |
65 | ## Usage
66 |
67 | #### Global configuration
68 |
69 | ```
70 | Config.build()
71 | .setHeader(new MeterialHead())
72 | .setFooter(new MeterialFooter())
73 | .setResistance(new Damping())
74 | .writeLog(true)
75 | .perform();
76 | ```
77 | #### Independent changes
78 |
79 | ```
80 | refresh.setIHeaderView(new SinaRefreshHeader());
81 | ```
82 |
83 | #### header fixed
84 |
85 | ```
86 | refresh.setHeadPin(ZRefreshLayout.HeadPin.PIN)
87 | ```
88 |
89 | #### auto refresh
90 |
91 | ```
92 | refresh.autoRefresh(haveAnimate)
93 | ```
94 |
95 | ### refresh's listener
96 | > refresh complete ,Remember to use:**zRefreshLayout.refreshComplete();**
97 |
98 | ```
99 | refresh.setPullListener(new ZRefreshLayout.PullListener() {
100 | @Override
101 | public void refresh(final ZRefreshLayout zRefreshLayout) {
102 | tv.postDelayed(new Runnable() {
103 | @Override
104 | public void run() {
105 | tv.setText("刷新完毕:" + i++);
106 | zRefreshLayout.refreshComplete();
107 | }
108 | }, 500);
109 | }
110 | });
111 | ```
112 |
113 | #### loadMore's Listener
114 | > if not setLoadMoreListener,not have loadMore feature;
115 |
116 | > loadMore complete ,Remember to use:**zRefreshLayout.loadMoreComplete();**
117 |
118 | ```
119 | refresh.setPullListener(new ZRefreshLayout.PullListener() {
120 | @Override
121 | public void refresh(final ZRefreshLayout zRefreshLayout) {
122 | tv.postDelayed(new Runnable() {
123 | @Override
124 | public void run() {
125 | tv.setText("刷新完毕:" + i++);
126 | zRefreshLayout.refreshComplete();
127 | }
128 | }, 500);
129 | }
130 | });
131 | ```
132 |
133 | > HeadView and FooterView 's custom and More advanced features,please see [**Wiki Document**](https://github.com/luhaoaimama1/ZRefreshLayout/wiki);;
134 |
135 | # Reference&Thanks:
136 |
137 | https://github.com/lcodecorex/TwinklingRefreshLayout
138 |
139 | https://github.com/tuesda/CircleRefreshLayout
140 |
141 | https://github.com/android-cjj/Android-MaterialRefreshLayout
142 |
143 | https://github.com/desmond1121/Android-Ptr-Comparison
144 |
145 | https://github.com/liaohuqiu/android-Ultra-Pull-To-Refresh
146 |
--------------------------------------------------------------------------------
/UpdateLog.md:
--------------------------------------------------------------------------------
1 | ## Update log
2 |
3 | >由于每个版本更新的东西较多,所以从现在开始每个版本都会贴上更新日志.
4 |
5 |
6 | ### 1.0.19
7 |
8 | * 修复auto刷新bug
9 | * 接口简化有助于Lambda的使用
10 | * 增加全局头部更改示例
11 | * 明明与内部逻辑的优化整理
12 |
13 | ### 1.0.18
14 |
15 | * 增加一些便利方法
16 |
17 | ### 1.0.17
18 |
19 | * 修复从新设置头部,刷新高度未变bug
20 |
21 | ### 1.0.16
22 |
23 | * 修复auto刷新bug
24 |
25 | ### 1.0.15
26 |
27 | * 全局刷新基本功能完成
28 | * 刷新加载委托逻辑
--------------------------------------------------------------------------------
/app-debug.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luhaoaimama1/ZRefreshLayout/1226a2d020b718687865b369810d069328e547cb/app-debug.apk
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-android-extensions'
4 | apply plugin: 'kotlin-kapt'
5 |
6 | android {
7 | compileSdkVersion 28
8 | defaultConfig {
9 | minSdkVersion 16
10 | versionCode 1
11 | versionName "1.0"
12 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | compileOptions {
21 | sourceCompatibility JavaVersion.VERSION_1_8
22 | targetCompatibility JavaVersion.VERSION_1_8
23 | }
24 | }
25 |
26 | dependencies {
27 | api fileTree(include: ['*.jar'], dir: 'libs')
28 | androidTestImplementation('androidx.test.espresso:espresso-core:3.1.0', {
29 | exclude group: 'com.android.support', module: 'support-annotations'
30 | })
31 | testImplementation 'junit:junit:4.12'
32 | api project(':zrefreshlayout')
33 | api 'androidx.appcompat:appcompat:1.0.0'
34 | api 'com.google.android.material:material:1.0.0'
35 | // apile 'com.github.luhaoaimama1:ZRefreshLayout:1.0.1'
36 | api 'com.github.luhaoaimama1:ZView:1.0.36'
37 | implementation 'com.github.luhaoaimama1:zone-sdk:2.2.1'
38 | // api 'com.github.luhaoaimama1:zone-sdk:1.0.98'
39 | implementation'com.github.luhaoaimama1:ZAdapter3:1.0.94'
40 | // api 'com.github.luhaoaimama1:ZAdapter:1.1.0'
41 | api "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
42 | api 'com.google.code.gson:gson:2.8.2'
43 | implementation "io.reactivex:rxjava:1.2.5"
44 | implementation "io.reactivex:rxandroid:1.2.1"
45 | }
46 | configurations {
47 | //排除module
48 | compile.exclude group: 'org.jetbrains', module: 'annotations'
49 | }
50 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/fuzhipeng/Library/Android/sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/app/src/main/java/zone/com/zrefreshlayoutdemo/Apps.kt:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayoutdemo
2 |
3 | import android.app.Application
4 | import android.graphics.Color
5 | import com.zone.lib.Configure
6 | import zone.com.zrefreshlayout.Config
7 | import zone.com.zrefreshlayout.ZRefreshLayout
8 | import zone.com.zrefreshlayout.footer.MeterialFooter
9 | import zone.com.zrefreshlayout.header.MeterialHead
10 | import zone.com.zrefreshlayout.header.SinaRefreshHeader
11 | import zone.com.zrefreshlayout.resistance.DampingHalf
12 | import zone.com.zrefreshlayoutdemo.common.Constant
13 | import zone.com.zrefreshlayoutdemo.common.HeadSetting
14 | import zone.com.zrefreshlayoutdemo.header.WaveHead
15 |
16 | /**
17 | * @author Sergey Tarasevich (nostra13[at]gmail[dot]com)
18 | */
19 | class Apps : Application() {
20 | override fun onCreate() {
21 | super.onCreate()
22 | Configure.init(this)
23 | setGlobalHead(SP1.get(Constant.REFRESH_MODE, HeadSetting::class.java))
24 | }
25 |
26 | companion object {
27 |
28 | val COLORS_RED_GREEN_YELLOW = intArrayOf(Color.parseColor("#ffF44336"), Color.parseColor("#ff4CAF50"), Color.parseColor("#ffFFEB3B"))
29 |
30 | fun setDefaultHeader() {
31 | Config.build()
32 | .setHeader(MeterialHead(COLORS_RED_GREEN_YELLOW))
33 | .setHeadPin(ZRefreshLayout.HeadPin.NOT_PIN)
34 | .setFooter(MeterialFooter())
35 | .setResistance(DampingHalf())
36 | // .setHeader(new CircleRefresh())
37 | // .setResistance(new Damping2Head8per())
38 | .writeLog(true)
39 | .perform()
40 | }
41 |
42 |
43 | fun setGlobalHead(mHeadSetting: HeadSetting?) {
44 | val temp = Config.build()
45 | if (mHeadSetting == null) {
46 | setDefaultHeader()
47 | return
48 | }
49 | when (mHeadSetting.headmode) {
50 | HeadSetting.METERIAL -> temp.setHeader(MeterialHead(COLORS_RED_GREEN_YELLOW))
51 | HeadSetting.SINA -> temp.setHeader(SinaRefreshHeader())
52 | HeadSetting.WAVE -> {
53 | val waveHead = WaveHead()
54 | waveHead.resourceId = R.drawable.wave
55 | temp.setHeader(waveHead)
56 | }
57 | }
58 | temp.setHeadPin(mHeadSetting.headPin())
59 | .setFooter(MeterialFooter())
60 | .setResistance(DampingHalf())
61 | .writeLog(true)
62 | .perform()
63 | }
64 | }
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/app/src/main/java/zone/com/zrefreshlayoutdemo/AutoRefreshActivity.kt:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayoutdemo
2 |
3 | import android.os.Bundle
4 | import androidx.appcompat.app.AppCompatActivity
5 | import android.view.View
6 | import kotlinx.android.synthetic.main.unique_feature_copy.*
7 | import zone.com.zrefreshlayout.ZRefreshLayout
8 | import zone.com.zrefreshlayout.header.MeterialHead
9 |
10 | /**
11 | * Created by fuzhipeng on 2017/1/11.
12 | */
13 |
14 | class AutoRefreshActivity : AppCompatActivity(),View.OnClickListener {
15 |
16 | override fun onCreate(savedInstanceState: Bundle?) {
17 | super.onCreate(savedInstanceState)
18 | setContentView(R.layout.unique_feature_copy)
19 | refresh.iHeaderView = MeterialHead()
20 | refresh.headPin = ZRefreshLayout.HeadPin.PIN
21 | refresh.pullListener = ZRefreshLayout.PullListener { zRefreshLayout ->
22 | refresh.postDelayed({
23 | iv.setImageResource(R.drawable.aaaaaaaaaaaab)
24 | zRefreshLayout.refreshComplete()
25 | }, 2000)
26 | }
27 |
28 | }
29 |
30 | override fun onClick(view: View?) {
31 | when (view?.id) {
32 | R.id.tv -> refresh.postDelayed({ refresh.autoRefresh(false) }, 1000)
33 | R.id.tvAnimate -> refresh.postDelayed({ refresh.autoRefresh(true) }, 1000)
34 | else->{}
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/app/src/main/java/zone/com/zrefreshlayoutdemo/CircleHeaderActivity.kt:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayoutdemo
2 |
3 | import android.os.Bundle
4 | import androidx.appcompat.app.AppCompatActivity
5 | import kotlinx.android.synthetic.main.unique_feature.*
6 | import zone.com.zrefreshlayoutdemo.header.CircleRefresh
7 |
8 | /**
9 | * Created by fuzhipeng on 2017/1/11.
10 | */
11 |
12 | class CircleHeaderActivity : AppCompatActivity() {
13 |
14 | override fun onCreate(savedInstanceState: Bundle?) {
15 | super.onCreate(savedInstanceState)
16 | setContentView(R.layout.unique_feature)
17 | refresh.setIHeaderView(CircleRefresh())
18 | // refresh.setIResistance(new Damping2Head8per());
19 |
20 | tv.text = "包含滚动拦截后,准备就绪后,在滚动到特定位置! 还有下拉位置映射,刷新位置更改"
21 | refresh.setPullListener({ zRefreshLayout -> refresh.postDelayed({ zRefreshLayout.refreshComplete() }, 2000) }, { iv.setImageResource(R.drawable.aaaaaaaaaaaab) })
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/app/src/main/java/zone/com/zrefreshlayoutdemo/CirlcleActivity.kt:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayoutdemo
2 |
3 | import android.os.Bundle
4 | import androidx.appcompat.app.AppCompatActivity
5 | import android.util.Log
6 | import android.view.View
7 | import android.view.animation.LinearInterpolator
8 |
9 | import android.animation.Animator
10 | import android.animation.AnimatorListenerAdapter
11 | import kotlinx.android.synthetic.main.a_circle.*
12 | import zone.com.zanimate.value.ValueAnimatorProxy
13 | import zone.com.zrefreshlayout.utils.ScreenUtils
14 | import zone.com.zrefreshlayout.v4.MeterialCircle
15 |
16 | /**
17 | * [2017] by Zone
18 | */
19 |
20 | class CirlcleActivity : AppCompatActivity(), View.OnClickListener {
21 |
22 | var mMeterialCircle: MeterialCircle? = null
23 |
24 | private val valueAnimator = ValueAnimatorProxy.ofFloat(0F, 1f)
25 | .setDuration(1200)
26 | .setInterpolator(LinearInterpolator())
27 | .addUpdateListener { animation ->
28 | println("值?" + animation.animatedValue as Float)
29 | mMeterialCircle?.pullProgress(animation.animatedValue as Float)
30 | }
31 | .addListener(object : AnimatorListenerAdapter() {
32 | override fun onAnimationEnd(animation: Animator?) {
33 | super.onAnimationEnd(animation)
34 | mMeterialCircle?.start()
35 | }
36 | })
37 |
38 | override fun onCreate(savedInstanceState: Bundle?) {
39 | super.onCreate(savedInstanceState)
40 | setContentView(R.layout.a_circle)
41 | root.post {
42 | val screenPixs = ScreenUtils.getScreenPix(this@CirlcleActivity)
43 | mMeterialCircle = MeterialCircle(root, (screenPixs[1] * 0.2).toInt())
44 | root.addView(mMeterialCircle!!.view)
45 | }
46 | }
47 |
48 | override fun onClick(view: View?) {
49 | when (view?.id) {
50 | R.id.bt_start -> {
51 | if (valueAnimator.isRunning)
52 | valueAnimator.cancel()
53 | mMeterialCircle?.reset()
54 | valueAnimator.start()
55 | }
56 | R.id.bt_stop -> mMeterialCircle?.reset()
57 | R.id.bt_reStart -> mMeterialCircle?.startScaleDownAnimation { Log.e("CirlcleActivity", "over") }
58 | else -> {
59 | }
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/app/src/main/java/zone/com/zrefreshlayoutdemo/FlexibilityKtActivity.kt:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayoutdemo
2 |
3 | import android.os.Bundle
4 | import androidx.core.view.ViewCompat
5 | import androidx.appcompat.app.AppCompatActivity
6 | import android.view.View
7 | import android.widget.ImageView
8 | import java.util.ArrayList
9 | import com.zone.adapter3.QuickRcvAdapter
10 | import kotlinx.android.synthetic.main.a_flexibility.*
11 | import kotlinx.android.synthetic.main.a_flexibility.refresh
12 | import kotlinx.android.synthetic.main.a_flexibility.rv
13 | import zone.com.zrefreshlayout.IScroll
14 | import zone.com.zrefreshlayout.ZRefreshLayout
15 | import zone.com.zrefreshlayout.scroll.listener.ScrollScale
16 | import zone.com.zrefreshlayout.scroll.listener.ScrollScroll
17 | import zone.com.zrefreshlayoutdemo.delegate.MenuEntityDeletates
18 |
19 | /**
20 | * Created by fuzhipeng on 2017/1/10.
21 | */
22 |
23 | class FlexibilityKtActivity : AppCompatActivity(),View.OnClickListener {
24 |
25 | private val mDatas = ArrayList()
26 | private var adapter2: QuickRcvAdapter? = null
27 | var height: Int = 0
28 |
29 | init {
30 | var i: Int = 'A'.toInt()
31 | while (i <= 'H'.toInt()) {
32 | mDatas.add("" + i.toChar())
33 | i++
34 | }
35 | }
36 |
37 | override fun onCreate(savedInstanceState: Bundle?) {
38 | super.onCreate(savedInstanceState)
39 | setContentView(R.layout.a_flexibility)
40 | refresh!!.headPin=ZRefreshLayout.HeadPin.NOTHING
41 | iv.post { height = iv.height }
42 | rv!!.layoutManager = androidx.recyclerview.widget.LinearLayoutManager(this, androidx.recyclerview.widget.LinearLayoutManager.VERTICAL, false)
43 | adapter2= QuickRcvAdapter(this,mDatas).apply {
44 | addViewHolder(MenuEntityDeletates())
45 | relatedList(rv)
46 | }
47 | }
48 |
49 |
50 | override fun onClick(view: View?) {
51 | view?.let{
52 | val scrollScale = when (view.id) {
53 | R.id.bt_scroll -> arrayListOf(ScrollScroll(refresh!!))
54 | R.id.bt_scale -> arrayListOf(ScrollScale(refresh!!))
55 | R.id.bt_Header -> arrayListOf(ScrollHeadScroll(refresh!!, iv!!, height), ScrollScroll(refresh!!))
56 | else -> arrayListOf(ScrollScroll(refresh!!))
57 | }
58 | refresh!!.iScrollList.clear()
59 | refresh!!.iScrollList.addAll(scrollScale)
60 | }
61 | }
62 |
63 | class ScrollHeadScroll(mZRefreshLayout: ZRefreshLayout, val iv: ImageView, val height: Int) : IScroll(mZRefreshLayout) {
64 |
65 | override fun scrollTo(fy: Int, isTriggerHeaderOnPullingDown: Boolean) {
66 | if (fy > 0) {
67 | val ph = 1 + fy.toFloat() / height.toFloat()
68 | ViewCompat.setPivotY(iv, 0f)
69 | ViewCompat.setScaleX(iv, ph)
70 | ViewCompat.setScaleY(iv, ph)
71 | }
72 | }
73 | }
74 | }
75 |
76 |
--------------------------------------------------------------------------------
/app/src/main/java/zone/com/zrefreshlayoutdemo/GlobalViewActivity.java:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayoutdemo;
2 |
3 | import android.os.Bundle;
4 | import androidx.appcompat.app.AppCompatActivity;
5 | import android.widget.TextView;
6 |
7 | import zone.com.zrefreshlayout.ZRefreshLayout;
8 |
9 | /**
10 | * Created by fuzhipeng on 2017/1/10.
11 | */
12 |
13 | public class GlobalViewActivity extends AppCompatActivity {
14 | private ZRefreshLayout refresh;
15 | private TextView tv;
16 | private int i = 0;
17 |
18 | @Override
19 | protected void onCreate(Bundle savedInstanceState) {
20 | super.onCreate(savedInstanceState);
21 | setContentView(R.layout.text);
22 | refresh = (ZRefreshLayout) findViewById(R.id.refresh);
23 | tv = (TextView) findViewById(R.id.tv);
24 | refresh.setLoadMoreListener(new ZRefreshLayout.LoadMoreListener() {
25 | @Override
26 | public void loadMore(final ZRefreshLayout zRefreshLayout) {
27 | tv.postDelayed(new Runnable() {
28 | @Override
29 | public void run() {
30 | tv.setText("加载更多:" + i++);
31 | zRefreshLayout.loadMoreComplete();
32 | }
33 | }, 2000);
34 | }
35 |
36 |
37 | });
38 | refresh.setPullListener(new ZRefreshLayout.PullListener() {
39 | @Override
40 | public void refresh(final ZRefreshLayout zRefreshLayout) {
41 | tv.postDelayed(new Runnable() {
42 | @Override
43 | public void run() {
44 | tv.setText("刷新完毕:" + i++);
45 | zRefreshLayout.refreshComplete();
46 | }
47 | }, 2000);
48 | }
49 |
50 | });
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/app/src/main/java/zone/com/zrefreshlayoutdemo/GridViewActivity.kt:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayoutdemo
2 |
3 | import android.os.Bundle
4 | import androidx.appcompat.app.AppCompatActivity
5 | import kotlinx.android.synthetic.main.grid.*
6 | import java.util.ArrayList
7 | import zone.com.zrefreshlayout.ZRefreshLayout
8 | import zone.com.zrefreshlayoutdemo.delegate.AdapterList
9 |
10 | /**
11 | * Created by fuzhipeng on 2017/1/10.
12 | */
13 |
14 | class GridViewActivity : AppCompatActivity() {
15 | private var i = 0
16 |
17 | private val mDatas = ArrayList()
18 | private var adapter2: AdapterList? = null
19 |
20 | init {
21 | run {
22 | var i: Int = 'A'.toInt()
23 | while (i <= 'Z'.toInt()) {
24 | mDatas.add("" + i.toChar())
25 | i++
26 | }
27 | }
28 | }
29 |
30 | override fun onCreate(savedInstanceState: Bundle?) {
31 | super.onCreate(savedInstanceState)
32 | setContentView(R.layout.grid)
33 | refresh.pullListener = ZRefreshLayout.PullListener { zRefreshLayout ->
34 | refresh.postDelayed({
35 | mDatas.add("刷新完毕:" + i++)
36 | adapter2!!.notifyDataSetChanged()
37 | zRefreshLayout.refreshComplete()
38 | }, 2000)
39 | }
40 | refresh.loadMoreListener = ZRefreshLayout.LoadMoreListener { zRefreshLayout ->
41 | refresh.postDelayed({
42 | mDatas.add("加载完毕:" + i++)
43 | adapter2!!.notifyDataSetChanged()
44 | zRefreshLayout.loadMoreComplete()
45 | }, 2000)
46 | }
47 |
48 | adapter2 = AdapterList(this, mDatas)
49 | gridView.adapter = adapter2
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/app/src/main/java/zone/com/zrefreshlayoutdemo/ListViewActivity.kt:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayoutdemo
2 |
3 | import android.graphics.Color
4 | import android.os.Bundle
5 | import androidx.appcompat.app.AppCompatActivity
6 | import java.util.ArrayList
7 | import kotlinx.android.synthetic.main.list.*
8 | import zone.com.zrefreshlayout.ZRefreshLayout
9 | import zone.com.zrefreshlayoutdemo.delegate.AdapterList
10 |
11 | /**
12 | * Created by fuzhipeng on 2017/1/10.
13 | */
14 |
15 | class ListViewActivity : AppCompatActivity() {
16 | private var i = 0
17 | private val mDatas = ArrayList()
18 | private var adapter2: AdapterList? = null
19 | init {
20 | run {
21 | var i: Int = 'A'.toInt()
22 | while (i <= 'H'.toInt()) {
23 | mDatas.add("" + i.toChar())
24 | i++
25 | }
26 | }
27 | }
28 |
29 | override fun onCreate(savedInstanceState: Bundle?) {
30 | super.onCreate(savedInstanceState)
31 | setContentView(R.layout.list)
32 | refresh.loadMoreListener = ZRefreshLayout.LoadMoreListener { zRefreshLayout ->
33 | refresh.postDelayed({
34 | mDatas.add("加载完毕:" + i++)
35 | adapter2!!.notifyDataSetChanged()
36 | zRefreshLayout.loadMoreComplete()
37 | }, 2000)
38 | }
39 | refresh.pullListener = ZRefreshLayout.PullListener { zRefreshLayout ->
40 | listView!!.smoothScrollToPosition(0)
41 | refresh.postDelayed({
42 | mDatas.add("刷新完毕:" + i++)
43 | adapter2!!.notifyDataSetChanged()
44 | zRefreshLayout.refreshComplete()
45 | }, 2000)
46 | }
47 |
48 | adapter2 = AdapterList(this, mDatas)
49 | listView.adapter = adapter2
50 | }
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/app/src/main/java/zone/com/zrefreshlayoutdemo/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayoutdemo
2 |
3 | import android.content.Intent
4 | import android.os.Bundle
5 | import androidx.appcompat.app.AppCompatActivity
6 | import android.view.View
7 | import com.zone.lib.LogZSDK
8 | import com.zone.lib.ZLogger
9 | import com.zone.lib.base.controller.activity.BaseFeatureActivity
10 | import com.zone.lib.base.controller.activity.controller.SwipeBackActivityController
11 | import zone.com.zrefreshlayoutdemo.common.Constant
12 | import zone.com.zrefreshlayoutdemo.common.HeadSetting
13 |
14 | class MainActivity : BaseFeatureActivity() {
15 | companion object {
16 | //还原最开始的log配置 如果某次配置一次特殊的 打印完后的记得还原配置
17 | @JvmStatic
18 | fun initLogger() {
19 | ZLogger.logLevelList.clear()
20 | ZLogger.mayLoggerList.clear()
21 | // ZLogger.mayLoggerList.addAll(listOf(LogCustomView, LogZSDK))
22 | }
23 | }
24 |
25 | override fun initDefaultConifg() {
26 | unRegisterPrestener(SwipeBackActivityController::class.java)
27 | }
28 |
29 | override fun initData() {
30 | permissionCheckStorageMustPermit()
31 | setContentView(R.layout.main)
32 | }
33 | override fun onStoragePermit() {
34 | super.onStoragePermit()
35 | }
36 |
37 | override fun onStorageDeniedMustPermit() {
38 | super.onStorageDeniedMustPermit()
39 | finish()
40 | }
41 |
42 |
43 | override fun setContentView() {
44 | }
45 |
46 | override fun setListener() {
47 | }
48 |
49 |
50 | override fun onClick(view: View?) {
51 | view?.let {
52 | if (it.id == R.id.globalView)
53 | Apps.setGlobalHead(SP1.get(Constant.REFRESH_MODE, HeadSetting::class.java))
54 | else
55 | Apps.setDefaultHeader()
56 |
57 | when (it.id) {
58 | R.id.globalView -> startActivity(Intent(this, GlobalViewActivity::class.java))
59 | R.id.tv_mode -> startActivity(Intent(this, SettingActivity::class.java))
60 | R.id.textView -> startActivity(Intent(this, TextViewActivity::class.java))
61 | R.id.listView -> startActivity(Intent(this, ListViewActivity::class.java))
62 | R.id.recyclerView -> startActivity(Intent(this, RecyclerViewActivity::class.java))
63 | R.id.gridView -> startActivity(Intent(this, GridViewActivity::class.java))
64 | R.id.scrollerView -> startActivity(Intent(this, ScrollerViewActivity::class.java))
65 | R.id.webView -> startActivity(Intent(this, WebViewActivity::class.java))
66 | R.id.autoRefresh -> startActivity(Intent(this, AutoRefreshActivity::class.java))
67 | R.id.pinContent -> startActivity(Intent(this, PinContentActivity::class.java))
68 | R.id.uniqueFeature -> startActivity(Intent(this, UniqueFeatureActivity::class.java))
69 | R.id.refreshAblePosition -> startActivity(Intent(this, RefreshPositionActivity::class.java))
70 | R.id.resistance -> startActivity(Intent(this, ResistanceActivity::class.java))
71 | R.id.waveHeader -> startActivity(Intent(this, WaveHeaderActivity::class.java))
72 | R.id.circleHeader -> startActivity(Intent(this, CircleHeaderActivity::class.java))
73 | R.id.sinaRefresh -> startActivity(Intent(this, SinaHeaderActivity::class.java))
74 | R.id.meterialHeader -> startActivity(Intent(this, MeterialHeaderActivity::class.java))
75 | R.id.cirlcleActivity -> startActivity(Intent(this, CirlcleActivity::class.java))
76 | R.id.flexibilityListViewActivity -> startActivity(Intent(this, FlexibilityKtActivity::class.java))
77 | R.id.nestScroller -> startActivity(Intent(this, ScrollerNesttActivity::class.java))
78 | else -> {
79 | }
80 | }
81 | }
82 |
83 | }
84 |
85 | }
86 |
--------------------------------------------------------------------------------
/app/src/main/java/zone/com/zrefreshlayoutdemo/MeterialHeaderActivity.kt:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayoutdemo
2 |
3 | import android.os.Bundle
4 | import androidx.appcompat.app.AppCompatActivity
5 | import com.zone.lib.utils.activity_fragment_ui.ToastUtils
6 | import kotlinx.android.synthetic.main.auto_refresh.*
7 | import zone.com.zrefreshlayout.ZRefreshLayout
8 | import zone.com.zrefreshlayout.footer.MeterialFooter
9 | import zone.com.zrefreshlayout.header.MeterialHead
10 |
11 | /**
12 | * Created by fuzhipeng on 2017/1/11.
13 | */
14 |
15 | class MeterialHeaderActivity : AppCompatActivity() {
16 |
17 | override fun onCreate(savedInstanceState: Bundle?) {
18 | super.onCreate(savedInstanceState)
19 | setContentView(R.layout.auto_refresh)
20 | refresh.iHeaderView = MeterialHead()
21 |
22 | refresh.pullListener = ZRefreshLayout.PullListener { zRefreshLayout ->
23 | refresh.postDelayed({
24 | iv.setImageResource(R.drawable.aaaaaaaaaaaab)
25 | zRefreshLayout.refreshComplete()
26 | }, 2000)
27 | }
28 |
29 | refresh.iFooterView = MeterialFooter()
30 | refresh.loadMoreListener = ZRefreshLayout.LoadMoreListener { zRefreshLayout ->
31 | refresh.postDelayed({
32 | ToastUtils.showShort(this@MeterialHeaderActivity, "加载更多")
33 | zRefreshLayout.loadMoreComplete()
34 | }, 2000)
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/app/src/main/java/zone/com/zrefreshlayoutdemo/PinContentActivity.kt:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayoutdemo
2 |
3 | import android.os.Bundle
4 | import androidx.appcompat.app.AppCompatActivity
5 | import kotlinx.android.synthetic.main.auto_refresh.*
6 | import zone.com.zrefreshlayout.ZRefreshLayout
7 |
8 | /**
9 | * Created by fuzhipeng on 2017/1/11.
10 | */
11 |
12 | class PinContentActivity : AppCompatActivity() {
13 |
14 | override fun onCreate(savedInstanceState: Bundle?) {
15 | super.onCreate(savedInstanceState)
16 | setContentView(R.layout.auto_refresh)
17 | refresh.headPin = ZRefreshLayout.HeadPin.PIN
18 | refresh.pullListener = ZRefreshLayout.PullListener { zRefreshLayout ->
19 | refresh.postDelayed({
20 | iv.setImageResource(R.drawable.aaaaaaaaaaaab)
21 | zRefreshLayout.refreshComplete()
22 | }, 2000)
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/app/src/main/java/zone/com/zrefreshlayoutdemo/RecyclerViewActivity.kt:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayoutdemo
2 |
3 | import android.graphics.Color
4 | import android.os.Bundle
5 | import androidx.appcompat.app.AppCompatActivity
6 | import com.zone.adapter3.QuickRcvAdapter
7 | import java.util.ArrayList
8 | import kotlinx.android.synthetic.main.rev.*
9 | import zone.com.zrefreshlayout.ZRefreshLayout
10 | import zone.com.zrefreshlayoutdemo.delegate.MenuEntityDeletates
11 |
12 | /**
13 | * Created by fuzhipeng on 2017/1/10.
14 | */
15 |
16 | class RecyclerViewActivity : AppCompatActivity() {
17 | private var i = 0
18 | private val mDatas = ArrayList()
19 | private var adapter2: QuickRcvAdapter? = null
20 |
21 | companion object {
22 | val colorArry = intArrayOf(Color.WHITE, Color.GREEN, Color.YELLOW, Color.CYAN)
23 | }
24 |
25 | init {
26 | run {
27 | var i: Int = 'A'.toInt()
28 | while (i <= 'H'.toInt()) {
29 | mDatas.add("" + i.toChar())
30 | i++
31 | }
32 | }
33 | }
34 |
35 | override fun onCreate(savedInstanceState: Bundle?) {
36 | super.onCreate(savedInstanceState)
37 | setContentView(R.layout.rev)
38 | refresh.headPin=ZRefreshLayout.HeadPin.PIN
39 | refresh.pullListener = ZRefreshLayout.PullListener { zRefreshLayout ->
40 | // refresh.postDelayed({
41 | mDatas.add("刷新完毕:" + i++)
42 | adapter2!!.notifyDataSetChanged()
43 | zRefreshLayout.refreshComplete()
44 | // }, 2000)
45 | }
46 | refresh.loadMoreListener = ZRefreshLayout.LoadMoreListener { zRefreshLayout ->
47 | refresh.postDelayed({
48 | mDatas.add("加载完毕:" + i++)
49 | adapter2!!.notifyDataSetChanged()
50 | zRefreshLayout.loadMoreComplete()
51 | }, 2000)
52 | }
53 | rv!!.layoutManager = androidx.recyclerview.widget.LinearLayoutManager(this, androidx.recyclerview.widget.LinearLayoutManager.VERTICAL, false)
54 | adapter2=QuickRcvAdapter(this,mDatas).apply {
55 | addViewHolder(MenuEntityDeletates())
56 | relatedList(rv)
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/app/src/main/java/zone/com/zrefreshlayoutdemo/RefreshPositionActivity.kt:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayoutdemo
2 |
3 | import android.os.Bundle
4 | import androidx.appcompat.app.AppCompatActivity
5 | import kotlinx.android.synthetic.main.unique_feature.*
6 | import zone.com.zrefreshlayout.ZRefreshLayout
7 | import zone.com.zrefreshlayoutdemo.header.SinaRefreshViewRefreshPositionTest
8 |
9 | /**
10 | * Created by fuzhipeng on 2017/1/11.
11 | */
12 |
13 | class RefreshPositionActivity : AppCompatActivity() {
14 |
15 | override fun onCreate(savedInstanceState: Bundle?) {
16 | super.onCreate(savedInstanceState)
17 | setContentView(R.layout.unique_feature)
18 | tv.text = "下拉到头部一半,则可刷新!"
19 | refresh.setIHeaderView(SinaRefreshViewRefreshPositionTest())
20 | refresh.pullListener = ZRefreshLayout.PullListener { zRefreshLayout ->
21 | refresh.postDelayed({
22 | iv.setImageResource(R.drawable.aaaaaaaaaaaab)
23 | zRefreshLayout.refreshComplete()
24 | }, 2000)
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/app/src/main/java/zone/com/zrefreshlayoutdemo/ResistanceActivity.kt:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayoutdemo
2 |
3 | import android.os.Bundle
4 | import androidx.appcompat.app.AppCompatActivity
5 | import kotlinx.android.synthetic.main.unique_feature.*
6 | import zone.com.zrefreshlayout.ZRefreshLayout
7 | import zone.com.zrefreshlayout.resistance.DampingHalfToHead
8 |
9 | /**
10 | * Created by fuzhipeng on 2017/1/11.
11 | */
12 |
13 | class ResistanceActivity : AppCompatActivity() {
14 |
15 | override fun onCreate(savedInstanceState: Bundle?) {
16 | super.onCreate(savedInstanceState)
17 | setContentView(R.layout.unique_feature)
18 | refresh.iResistance = DampingHalfToHead()
19 | tv.text = "下拉到头部后不可继续!"
20 | refresh.pullListener = ZRefreshLayout.PullListener { zRefreshLayout ->
21 | refresh.postDelayed({
22 | iv.setImageResource(R.drawable.aaaaaaaaaaaab)
23 | zRefreshLayout.refreshComplete()
24 | }, 2000)
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/app/src/main/java/zone/com/zrefreshlayoutdemo/SPManager.kt:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayoutdemo
2 |
3 | import com.zone.lib.utils.data.file2io2data.ZSharePerference
4 |
5 | /**
6 | *[2018/12/11] by Zone
7 | */
8 | object SP1 : ZSharePerference("SP1")
--------------------------------------------------------------------------------
/app/src/main/java/zone/com/zrefreshlayoutdemo/ScrollerNesttActivity.kt:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayoutdemo
2 | import android.os.Bundle
3 | import androidx.appcompat.app.AppCompatActivity
4 | import java.util.ArrayList
5 | import com.zone.adapter3.QuickRcvAdapter
6 | import kotlinx.android.synthetic.main.a_scroll_recycler_nest.*
7 | import zone.com.zrefreshlayout.ZRefreshLayout
8 | import zone.com.zrefreshlayoutdemo.delegate.MenuEntityDeletates
9 |
10 | /**
11 | * Created by fuzhipeng on 2017/1/10.
12 | */
13 |
14 | class ScrollerNesttActivity : AppCompatActivity() {
15 | private var i = 0
16 | private val mDatas = ArrayList()
17 | private var adapter2: QuickRcvAdapter? = null
18 |
19 | init {
20 | run {
21 | var i: Int = 'A'.toInt()
22 | while (i <= 'T'.toInt()) {
23 | mDatas.add("" + i.toChar())
24 | i++
25 | }
26 | }
27 | }
28 |
29 | override fun onCreate(savedInstanceState: Bundle?) {
30 | super.onCreate(savedInstanceState)
31 | setContentView(R.layout.a_scroll_recycler_nest)
32 | setSupportActionBar(id_toolbar)
33 |
34 | refresh.pullListener = ZRefreshLayout.PullListener { zRefreshLayout ->
35 | refresh.postDelayed({
36 | mDatas.add("刷新完毕:" + i++)
37 | adapter2!!.notifyDataSetChanged()
38 | zRefreshLayout.refreshComplete()
39 | }, 2000)
40 | }
41 | refresh.loadMoreListener = ZRefreshLayout.LoadMoreListener { zRefreshLayout ->
42 | refresh.postDelayed({
43 | mDatas.add("加载完毕:" + i++)
44 | adapter2!!.notifyDataSetChanged()
45 | zRefreshLayout.loadMoreComplete()
46 | }, 2000)
47 | }
48 | rv.layoutManager = androidx.recyclerview.widget.LinearLayoutManager(this, androidx.recyclerview.widget.LinearLayoutManager.VERTICAL, false)
49 | adapter2= QuickRcvAdapter(this,mDatas).apply {
50 | addViewHolder(MenuEntityDeletates())
51 | relatedList(rv)
52 | }
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/app/src/main/java/zone/com/zrefreshlayoutdemo/ScrollerViewActivity.kt:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayoutdemo
2 |
3 | import android.os.Bundle
4 | import androidx.appcompat.app.AppCompatActivity
5 | import kotlinx.android.synthetic.main.scroller.*
6 | import zone.com.zrefreshlayout.ZRefreshLayout
7 |
8 | /**
9 | * Created by fuzhipeng on 2017/1/10.
10 | */
11 |
12 | class ScrollerViewActivity : AppCompatActivity() {
13 | internal var i = 0
14 |
15 | override fun onCreate(savedInstanceState: Bundle?) {
16 | super.onCreate(savedInstanceState)
17 | setContentView(R.layout.scroller)
18 |
19 | initText()
20 | refresh.loadMoreListener = ZRefreshLayout.LoadMoreListener { zRefreshLayout ->
21 | refresh.postDelayed({
22 | tv1.text = "TV1:加载次数$i"
23 | tv2.text = "TV2:加载次数$i"
24 | tv3.text = "TV3:加载次数$i"
25 | zRefreshLayout.loadMoreComplete()
26 | }, 2000)
27 | }
28 | refresh.pullListener = ZRefreshLayout.PullListener { zRefreshLayout ->
29 | refresh.postDelayed({
30 | i++
31 | initText()
32 | zRefreshLayout.refreshComplete()
33 | }, 2000)
34 | }
35 | }
36 |
37 | private fun initText() {
38 | tv1.text = "TV1:刷新次数$i"
39 | tv2.text = "TV2:刷新次数$i"
40 | tv3.text = "TV3:刷新次数$i"
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/app/src/main/java/zone/com/zrefreshlayoutdemo/SettingActivity.kt:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayoutdemo
2 |
3 | import android.os.Bundle
4 | import androidx.annotation.IdRes
5 | import androidx.appcompat.app.AppCompatActivity
6 | import android.view.View
7 | import android.widget.RadioGroup
8 | import kotlinx.android.synthetic.main.a_setting.*
9 | import zone.com.zrefreshlayout.ZRefreshLayout
10 | import zone.com.zrefreshlayoutdemo.common.Constant
11 | import zone.com.zrefreshlayoutdemo.common.HeadSetting
12 |
13 | /**
14 | * MIT License
15 | * Copyright (c) [2018] [Zone]
16 | */
17 |
18 | class SettingActivity : AppCompatActivity(), RadioGroup.OnCheckedChangeListener, View.OnClickListener {
19 | private var mHeadSetting: HeadSetting? = null
20 |
21 | override fun onCreate(savedInstanceState: Bundle?) {
22 | super.onCreate(savedInstanceState)
23 | setContentView(R.layout.a_setting)
24 | rb_pin!!.setOnCheckedChangeListener(this)
25 | rb_head!!.setOnCheckedChangeListener(this)
26 | mHeadSetting = SP1.get(Constant.REFRESH_MODE, HeadSetting::class.java)
27 | if (mHeadSetting == null) {
28 | mHeadSetting = HeadSetting()
29 | rb_head_meterial!!.performClick()
30 | rb_pin_false!!.performClick()
31 | } else {
32 | when (mHeadSetting!!.headmode) {
33 | HeadSetting.METERIAL -> rb_head_meterial!!.performClick()
34 | HeadSetting.SINA -> rb_head_sina!!.performClick()
35 | HeadSetting.WAVE -> rb_head_wave!!.performClick()
36 | }
37 | if (mHeadSetting!!.headPin() == ZRefreshLayout.HeadPin.PIN)
38 | rb_pin_true!!.performClick()
39 | else
40 | rb_pin_false!!.performClick()
41 | }
42 |
43 | }
44 |
45 | override fun onClick(v: View?) {
46 | v?.let {
47 | when (it.id) {
48 | R.id.tv_Clear -> {
49 | SP1.remove(Constant.REFRESH_MODE)
50 | Apps.setDefaultHeader()
51 | }
52 | R.id.Save -> {
53 | SP1.put(Constant.REFRESH_MODE, mHeadSetting)
54 | Apps.setGlobalHead(mHeadSetting)
55 | }
56 | }
57 | finish()
58 | }
59 | }
60 |
61 | override fun onCheckedChanged(group: RadioGroup, @IdRes checkedId: Int) {
62 | if (group === rb_pin)
63 | onCheckedChanged_Pin(checkedId)
64 | if (group === rb_head)
65 | onCheckedChanged_Head(checkedId)
66 | }
67 |
68 | fun onCheckedChanged_Pin(@IdRes checkedId: Int) {
69 | if (checkedId == R.id.rb_pin_true)
70 | mHeadSetting!!.setPin(ZRefreshLayout.HeadPin.PIN)
71 | else
72 | mHeadSetting!!.setPin(ZRefreshLayout.HeadPin.NOT_PIN)
73 | }
74 |
75 | fun onCheckedChanged_Head(@IdRes checkedId: Int) {
76 | when (checkedId) {
77 | R.id.rb_head_meterial -> mHeadSetting!!.headmode = HeadSetting.METERIAL
78 | R.id.rb_head_sina -> mHeadSetting!!.headmode = HeadSetting.SINA
79 | R.id.rb_head_wave -> mHeadSetting!!.headmode = HeadSetting.WAVE
80 | }
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/app/src/main/java/zone/com/zrefreshlayoutdemo/SinaHeaderActivity.kt:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayoutdemo
2 |
3 | import android.os.Bundle
4 | import androidx.appcompat.app.AppCompatActivity
5 |
6 | import com.zone.lib.utils.activity_fragment_ui.ToastUtils
7 |
8 | import kotlinx.android.synthetic.main.auto_refresh.*
9 | import zone.com.zrefreshlayout.ZRefreshLayout
10 | import zone.com.zrefreshlayout.footer.LoadFooter
11 | import zone.com.zrefreshlayout.header.SinaRefreshHeader
12 |
13 | /**
14 | * Created by fuzhipeng on 2017/1/11.
15 | */
16 |
17 | class SinaHeaderActivity : AppCompatActivity() {
18 |
19 | override fun onCreate(savedInstanceState: Bundle?) {
20 | super.onCreate(savedInstanceState)
21 | setContentView(R.layout.auto_refresh)
22 | refresh.iHeaderView = SinaRefreshHeader()
23 | refresh.pullListener = ZRefreshLayout.PullListener { zRefreshLayout ->
24 | refresh.postDelayed({
25 | iv.setImageResource(R.drawable.aaaaaaaaaaaab)
26 | zRefreshLayout.refreshComplete()
27 | }, 2000)
28 | }
29 |
30 | refresh.iFooterView = LoadFooter()
31 | refresh.loadMoreListener = ZRefreshLayout.LoadMoreListener { zRefreshLayout ->
32 | refresh.postDelayed({
33 | ToastUtils.showShort(this@SinaHeaderActivity, "加载更多")
34 | zRefreshLayout.loadMoreComplete()
35 | }, 2000)
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/app/src/main/java/zone/com/zrefreshlayoutdemo/TextViewActivity.java:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayoutdemo;
2 |
3 | import android.os.Bundle;
4 | import androidx.appcompat.app.AppCompatActivity;
5 | import android.widget.TextView;
6 |
7 | import zone.com.zrefreshlayout.ZRefreshLayout;
8 |
9 | /**
10 | * Created by fuzhipeng on 2017/1/10.
11 | */
12 |
13 | public class TextViewActivity extends AppCompatActivity {
14 | private ZRefreshLayout refresh;
15 | private TextView tv;
16 | private int i = 0;
17 |
18 | @Override
19 | protected void onCreate(Bundle savedInstanceState) {
20 | super.onCreate(savedInstanceState);
21 | setContentView(R.layout.text);
22 | refresh = (ZRefreshLayout) findViewById(R.id.refresh);
23 | tv = (TextView) findViewById(R.id.tv);
24 | refresh.setLoadMoreListener(new ZRefreshLayout.LoadMoreListener() {
25 | @Override
26 | public void loadMore(final ZRefreshLayout zRefreshLayout) {
27 | tv.postDelayed(new Runnable() {
28 | @Override
29 | public void run() {
30 | tv.setText("加载更多:" + i++);
31 | zRefreshLayout.loadMoreComplete();
32 | }
33 | }, 500);
34 | }
35 |
36 | });
37 | refresh.setPullListener(new ZRefreshLayout.PullListener() {
38 | @Override
39 | public void refresh(final ZRefreshLayout zRefreshLayout) {
40 | tv.postDelayed(new Runnable() {
41 | @Override
42 | public void run() {
43 | tv.setText("刷新完毕:" + i++);
44 | zRefreshLayout.refreshComplete();
45 | }
46 | }, 500);
47 | }
48 | });
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/app/src/main/java/zone/com/zrefreshlayoutdemo/UniqueFeatureActivity.kt:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayoutdemo
2 |
3 | import android.os.Bundle
4 | import androidx.appcompat.app.AppCompatActivity
5 | import kotlinx.android.synthetic.main.unique_feature.*
6 | import zone.com.zrefreshlayout.ZRefreshLayout
7 |
8 | /**
9 | * Created by fuzhipeng on 2017/1/11.
10 | */
11 |
12 | class UniqueFeatureActivity : AppCompatActivity() {
13 |
14 | override fun onCreate(savedInstanceState: Bundle?) {
15 | super.onCreate(savedInstanceState)
16 | setContentView(R.layout.unique_feature)
17 | refresh.pullListener = ZRefreshLayout.PullListener { zRefreshLayout ->
18 | refresh.postDelayed({
19 | iv.setImageResource(R.drawable.aaaaaaaaaaaab)
20 | zRefreshLayout.refreshComplete()
21 | }, 2000)
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/app/src/main/java/zone/com/zrefreshlayoutdemo/WaveHeaderActivity.kt:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayoutdemo
2 |
3 | import android.os.Bundle
4 | import androidx.appcompat.app.AppCompatActivity
5 | import kotlinx.android.synthetic.main.unique_feature.*
6 | import zone.com.zrefreshlayout.ZRefreshLayout
7 | import zone.com.zrefreshlayoutdemo.header.WaveHead
8 |
9 | /**
10 | * Created by fuzhipeng on 2017/1/11.
11 | */
12 |
13 | class WaveHeaderActivity : AppCompatActivity() {
14 |
15 | override fun onCreate(savedInstanceState: Bundle?) {
16 | super.onCreate(savedInstanceState)
17 | setContentView(R.layout.unique_feature)
18 | val waveHead = WaveHead()
19 | waveHead.resourceId = R.drawable.wave
20 | refresh.iHeaderView = waveHead
21 |
22 | tv.text = "写着玩的没啥用~"
23 | refresh.pullListener = ZRefreshLayout.PullListener { zRefreshLayout ->
24 | refresh.postDelayed({
25 | iv.setImageResource(R.drawable.aaaaaaaaaaaab)
26 | zRefreshLayout.refreshComplete()
27 | }, 2000)
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/app/src/main/java/zone/com/zrefreshlayoutdemo/WebViewActivity.kt:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayoutdemo
2 |
3 | import android.os.Bundle
4 | import androidx.appcompat.app.AppCompatActivity
5 | import android.webkit.WebView
6 | import android.webkit.WebViewClient
7 | import android.widget.Toast
8 | import kotlinx.android.synthetic.main.web.*
9 | import zone.com.zrefreshlayout.ZRefreshLayout
10 |
11 | /**
12 | * Created by fuzhipeng on 2017/1/10.
13 | */
14 |
15 | class WebViewActivity : AppCompatActivity() {
16 |
17 |
18 | override fun onCreate(savedInstanceState: Bundle?) {
19 | super.onCreate(savedInstanceState)
20 | setContentView(R.layout.web)
21 | rotate_header_web_view.settings.javaScriptEnabled = true
22 | rotate_header_web_view.webViewClient = object : WebViewClient() {
23 | override fun onPageFinished(view: WebView, url: String) {
24 | refresh.refreshComplete()
25 | }
26 | }
27 | refresh.pullListener = ZRefreshLayout.PullListener { rotate_header_web_view.loadUrl("http://luhaoaimama1.github.io") }
28 |
29 | refresh.loadMoreListener = ZRefreshLayout.LoadMoreListener {
30 | refresh.postDelayed({
31 | Toast.makeText(this@WebViewActivity, "load", Toast.LENGTH_SHORT).show()
32 | refresh.loadMoreComplete()
33 | }, 2000)
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/app/src/main/java/zone/com/zrefreshlayoutdemo/common/Constant.kt:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayoutdemo.common
2 |
3 | object Constant {
4 | val REFRESH_MODE = "REFRESH_MODE"
5 | }
--------------------------------------------------------------------------------
/app/src/main/java/zone/com/zrefreshlayoutdemo/common/HeadSetting.kt:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayoutdemo.common
2 |
3 | import zone.com.zrefreshlayout.ZRefreshLayout
4 |
5 | /**
6 | * MIT License
7 | * Copyright (c) [2018] [Zone]
8 | */
9 |
10 | class HeadSetting {
11 |
12 | var headmode: Int = 0
13 | private var headPin: ZRefreshLayout.HeadPin = ZRefreshLayout.HeadPin.NOT_PIN
14 |
15 | fun headPin(): ZRefreshLayout.HeadPin {
16 | return headPin
17 | }
18 |
19 | fun setPin(pin: ZRefreshLayout.HeadPin) {
20 | this.headPin = pin
21 | }
22 |
23 | companion object {
24 | val METERIAL = 0
25 | val SINA = 1
26 | val WAVE = 2
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/app/src/main/java/zone/com/zrefreshlayoutdemo/delegate/AdapterList.kt:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayoutdemo.delegate
2 |
3 | import android.content.Context
4 | import android.view.LayoutInflater
5 | import android.view.View
6 | import android.view.ViewGroup
7 | import android.widget.BaseAdapter
8 | import android.widget.TextView
9 | import zone.com.zrefreshlayoutdemo.R
10 | import zone.com.zrefreshlayoutdemo.RecyclerViewActivity
11 |
12 | class AdapterList(val context: Context, private val stuList: List) : BaseAdapter() {
13 |
14 | override fun getCount(): Int {
15 | return stuList.size
16 | }
17 |
18 | override fun getItem(position: Int): Any {
19 | return stuList[position]
20 | }
21 |
22 | override fun getItemId(position: Int): Long {
23 | return position.toLong()
24 | }
25 |
26 | override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
27 | val view = LayoutInflater.from(context).inflate(R.layout.item_menu, null)
28 | val tv = view.findViewById(R.id.tv)
29 | tv.setText( stuList.get(position))
30 | val i = RecyclerViewActivity.colorArry[position %
31 | RecyclerViewActivity.colorArry.size]
32 | tv.setBackgroundColor(i)
33 | return view
34 | }
35 | }
--------------------------------------------------------------------------------
/app/src/main/java/zone/com/zrefreshlayoutdemo/delegate/MenuEntityDeletates.kt:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayoutdemo.delegate
2 |
3 | import com.zone.adapter3.bean.Holder
4 | import com.zone.adapter3.bean.ViewDelegates
5 | import zone.com.zrefreshlayoutdemo.R
6 | import zone.com.zrefreshlayoutdemo.RecyclerViewActivity
7 |
8 | class MenuEntityDeletates() : ViewDelegates() {
9 | override fun getLayoutId(): Int = R.layout.item_menu
10 |
11 | override fun fillData(posi: Int, entity: String?, holder: Holder>?) {
12 | holder?.setText(R.id.tv, entity)
13 | ?.setBackgroundColor(R.id.tv, RecyclerViewActivity.colorArry[holder.getAdapterPosition() % RecyclerViewActivity.colorArry.size])
14 | }
15 |
16 | }
--------------------------------------------------------------------------------
/app/src/main/java/zone/com/zrefreshlayoutdemo/header/CircleRefresh.java:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayoutdemo.header;
2 |
3 | import android.app.Activity;
4 | import android.graphics.Color;
5 | import androidx.annotation.NonNull;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.widget.LinearLayout;
9 |
10 | import zone.com.zrefreshlayout.AUtils;
11 | import zone.com.zrefreshlayout.IScroll;
12 | import zone.com.zrefreshlayout.ScrollAnimation;
13 | import zone.com.zrefreshlayout.IHeaderView;
14 | import zone.com.zrefreshlayout.R;
15 | import zone.com.zrefreshlayout.ZRefreshLayout;
16 | import zone.com.zrefreshlayout.utils.ScreenUtils;
17 | import zone.com.zrefreshlayoutdemo.header.view.AnimationView;
18 | import static zone.com.zrefreshlayout.utils.LogUtils.log;
19 | /**
20 | * Created by fuzhipeng on 2017/1/13.
21 | */
22 |
23 | public class CircleRefresh implements IHeaderView {
24 |
25 | private View rootView;
26 | private AnimationView mHeaderWaveCircle;
27 | private int mHeaderCircleSmaller = 6;
28 | private IScroll iScroll;
29 | private LinearLayout ll_main;
30 | private int[] screenPixs;
31 |
32 |
33 | @Override
34 | public View initView(ZRefreshLayout zRefreshLayout) {
35 | rootView = View.inflate(zRefreshLayout.getContext(), R.layout.header_meterial, null);
36 | // rootView.setBackgroundColor(Color.RED);
37 | //注意inflate那种模式 第一层需要空出去 不然会wrapcontent
38 | ll_main = (LinearLayout) rootView.findViewById(R.id.ll_main);
39 | screenPixs = ScreenUtils.getScreenPix((Activity) zRefreshLayout.getContext());
40 | ll_main.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT
41 | , (int) (screenPixs[1] * 0.2)));
42 | AUtils.setHeaderHeightToRefresh(zRefreshLayout,(int) (screenPixs[1] * 0.2*0.8));
43 | addView();
44 | return rootView;
45 | }
46 |
47 | @NonNull
48 | @Override
49 | public View getView() {
50 | return rootView;
51 | }
52 |
53 | private void addView() {
54 | ll_main.removeAllViews();
55 | mHeaderWaveCircle = new AnimationView(rootView.getContext());
56 | mHeaderWaveCircle.setBackgroundColor(Color.parseColor("#ffdb6e"));
57 | LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, (int) (screenPixs[1] * 0.2));
58 | mHeaderWaveCircle.setLayoutParams(params);
59 |
60 | ll_main.addView(mHeaderWaveCircle);
61 | mHeaderWaveCircle.setAniBackColor(Color.parseColor("#ffdb6e"));
62 | mHeaderWaveCircle.setAniForeColor(Color.WHITE);
63 | mHeaderWaveCircle.setRadius(mHeaderCircleSmaller);
64 | mHeaderWaveCircle.setOnViewAniDone(new AnimationView.OnViewAniDone() {
65 | @Override
66 | public void viewAniDone() {
67 | // Log.i(TAG, "should invoke");
68 | log("viewAniDone");
69 | //刷新动画 延迟完毕
70 | AUtils.smoothScrollTo_NotIntercept(iScroll,0);
71 | }
72 | });
73 | }
74 |
75 | @Override
76 | public void onPullingDown(float fraction, float headHeight) {
77 | }
78 |
79 | @Override
80 | public void refreshAble(boolean refreshAble) {
81 | if (refreshAble) {
82 | mHeaderWaveCircle.releaseDrag();
83 | }
84 | }
85 |
86 | private ScrollAnimation mScrollAnimation = ScrollAnimation.None;
87 |
88 | @Override
89 | public void animateBack(ScrollAnimation scrollAnimation, float fraction, float headHeight, ZRefreshLayout.HeadPin isPinContent) {
90 | mScrollAnimation = scrollAnimation;
91 | }
92 |
93 |
94 | //这里主要是对延迟刷新的处理
95 | @Override
96 | public boolean interceptAnimateBack(ScrollAnimation scrollAnimation, IScroll iScroll) {
97 | this.iScroll = iScroll;
98 | boolean result = false;
99 | if (mScrollAnimation != scrollAnimation && scrollAnimation == ScrollAnimation.Complete_BackAnimation) {
100 | mHeaderWaveCircle.setRefreshing(false);//刷新动画
101 | result = true;
102 | }
103 | mScrollAnimation = scrollAnimation;
104 | //返回结果就是是否拦截
105 | return result;
106 | }
107 |
108 | @Override
109 | public void onRefreshing(float headHeight, boolean isAutoRefresh) {
110 |
111 | }
112 |
113 | @Override
114 | public void onComplete() {
115 | addView();
116 | }
117 |
118 | @Override
119 | public IHeaderView clone_() {
120 | return new CircleRefresh();
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/app/src/main/java/zone/com/zrefreshlayoutdemo/header/SinaRefreshViewRefreshPositionTest.java:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayoutdemo.header;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import androidx.annotation.DrawableRes;
6 | import androidx.annotation.NonNull;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 | import android.view.animation.LinearInterpolator;
11 | import android.widget.ImageView;
12 | import android.widget.LinearLayout;
13 | import android.widget.TextView;
14 |
15 | import android.animation.ValueAnimator;
16 |
17 | import zone.com.zanimate.value.ValueAnimatorProxy;
18 | import zone.com.zrefreshlayout.AUtils;
19 | import zone.com.zrefreshlayout.IScroll;
20 | import zone.com.zrefreshlayout.ScrollAnimation;
21 | import zone.com.zrefreshlayout.IHeaderView;
22 | import zone.com.zrefreshlayout.R;
23 | import zone.com.zrefreshlayout.ZRefreshLayout;
24 | import zone.com.zrefreshlayout.utils.DensityUtils;
25 | import zone.com.zrefreshlayout.utils.ScreenUtils;
26 |
27 | import static zone.com.zrefreshlayout.utils.LogUtils.log;
28 |
29 | /**
30 | * Created by lcodecore on 2016/10/2.
31 | */
32 |
33 | public class SinaRefreshViewRefreshPositionTest implements IHeaderView {
34 |
35 | private ImageView refreshArrow;
36 | private ImageView loadingView;
37 | private TextView refreshTextView;
38 | private View rootView;
39 | private LinearLayout ll_main;
40 |
41 | public void setArrowResource(@DrawableRes int resId) {
42 | refreshArrow.setImageResource(resId);
43 | }
44 |
45 | public void setPullDownStr(String pullDownStr1) {
46 | pullDownStr = pullDownStr1;
47 | }
48 |
49 | public void setReleaseRefreshStr(String releaseRefreshStr1) {
50 | releaseRefreshStr = releaseRefreshStr1;
51 | }
52 |
53 | public void setRefreshingStr(String refreshingStr1) {
54 | refreshingStr = refreshingStr1;
55 | }
56 |
57 | private String pullDownStr = "下拉刷新";
58 | private String releaseRefreshStr = "释放刷新";
59 | private String refreshingStr = "正在刷新";
60 |
61 | @Override
62 | public IHeaderView clone_() {
63 | return new SinaRefreshViewRefreshPositionTest();
64 | }
65 |
66 | @Override
67 | public View initView(ZRefreshLayout zRefreshLayout) {
68 | rootView = LayoutInflater.from(zRefreshLayout.getContext()).inflate(R.layout.view_sinaheader,zRefreshLayout,false);
69 | //注意inflate那种模式 第一层需要空出去 不然会wrapcontent
70 | ll_main = (LinearLayout) rootView.findViewById(R.id.ll_main);
71 | refreshArrow = (ImageView) rootView.findViewById(R.id.iv_arrow);
72 | refreshTextView = (TextView) rootView.findViewById(R.id.tv);
73 | loadingView = (ImageView) rootView.findViewById(R.id.iv_loading);
74 | screenAdapter(zRefreshLayout,zRefreshLayout.getContext());
75 | return rootView;
76 | }
77 |
78 | @NonNull
79 | @Override
80 | public View getView() {
81 | return rootView;
82 | }
83 |
84 | private void screenAdapter(ZRefreshLayout zRefreshLayout, Context context) {
85 | int[] screenPixs = ScreenUtils.getScreenPix((Activity) context);
86 | ll_main.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT
87 | , (int) (screenPixs[1] * 0.1)));
88 | ViewGroup.LayoutParams refreshArrowLp = refreshArrow.getLayoutParams();
89 | refreshArrowLp.width = getAnInt(71, screenPixs, true);
90 | refreshArrowLp.height = getAnInt(71, screenPixs, false);
91 | refreshArrow.setLayoutParams(refreshArrowLp);
92 | ViewGroup.LayoutParams loadingViewLp = loadingView.getLayoutParams();
93 | loadingViewLp.width = getAnInt(71, screenPixs, true);
94 | loadingViewLp.height = getAnInt(71, screenPixs, false);
95 | loadingView.setLayoutParams(loadingViewLp);
96 | //注意TextSiz 要的是sp 需要px转过去
97 | refreshTextView.setTextSize(DensityUtils.px2sp(context, getAnInt(35, screenPixs, true)));
98 | AUtils.setHeaderHeightToRefresh(zRefreshLayout,(int) (screenPixs[1] * 0.05));
99 | }
100 |
101 | //我的参考图是1080*1920
102 | private int getAnInt(int dx, int[] screenPixs, boolean isWidth) {
103 | if (isWidth)
104 | return (int) (1F * dx / 1080 * screenPixs[0]);
105 | else
106 | return (int) (1F * dx / 1920 * screenPixs[1]);
107 | }
108 |
109 | @Override
110 | public void onPullingDown(float fraction, float headHeight) {
111 | }
112 |
113 | @Override
114 | public void refreshAble(boolean refreshAble) {
115 | if (refreshAble) {
116 | refreshArrow.animate().rotation(-180).start();
117 | refreshTextView.setText(releaseRefreshStr);
118 | } else {
119 | refreshTextView.setText(pullDownStr);
120 | refreshArrow.animate().rotation(0).start();
121 | }
122 | }
123 |
124 | @Override
125 | public void animateBack(ScrollAnimation scrollAnimation, float fraction, float headHeight,
126 | ZRefreshLayout.HeadPin mIScroll) {
127 | }
128 |
129 | @Override
130 | public boolean interceptAnimateBack(ScrollAnimation scrollAnimation, IScroll iScroll) {
131 | return false;
132 | }
133 |
134 | @Override
135 | public void onRefreshing(float headHeight, boolean isAutoRefresh) {
136 | refreshTextView.setText(refreshingStr);
137 | refreshArrow.setVisibility(View.GONE);
138 | loadingView.setVisibility(View.VISIBLE);
139 | valueAnimator.start();
140 | log("onRefreshing");
141 | }
142 |
143 | private ValueAnimatorProxy valueAnimator = ValueAnimatorProxy.ofInt(0, 360)
144 | .setDuration(1200)
145 | .setInterpolator(new LinearInterpolator())
146 | .setRepeatCount(ValueAnimator.INFINITE)
147 | .addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
148 | @Override
149 | public void onAnimationUpdate(ValueAnimator animation) {
150 | // 30 =360/12;
151 | // ZRefreshLayout.log("animation.getAnimatedValue():"+animation.getAnimatedValue()+"——————进度:"+((Integer) animation.getAnimatedValue()/30)*30F);
152 | loadingView.setRotation(((Integer) animation.getAnimatedValue() / 30) * 30F);
153 | }
154 | });
155 |
156 | @Override
157 | public void onComplete() {
158 | refreshArrow.setVisibility(View.VISIBLE);
159 | loadingView.setVisibility(View.GONE);
160 | if (valueAnimator.isRunning())
161 | valueAnimator.end();
162 | log("onComplete");
163 | }
164 |
165 |
166 | }
167 |
--------------------------------------------------------------------------------
/app/src/main/java/zone/com/zrefreshlayoutdemo/header/WaveHead.java:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayoutdemo.header;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.graphics.Bitmap;
6 | import android.graphics.ColorMatrix;
7 | import android.graphics.ColorMatrixColorFilter;
8 | import android.graphics.PorterDuff;
9 | import androidx.annotation.NonNull;
10 | import android.view.View;
11 | import android.view.ViewGroup;
12 | import android.widget.ImageView;
13 | import android.widget.LinearLayout;
14 |
15 | import android.animation.ValueAnimator;
16 | import com.zone.lib.utils.image.BitmapComposer;
17 | import com.zone.lib.utils.image.WaveHelper;
18 | import com.zone.lib.utils.image.compress2sample.SampleUtils;
19 |
20 | import zone.com.zanimate.value.ValueAnimatorProxy;
21 | import zone.com.zrefreshlayout.IScroll;
22 | import zone.com.zrefreshlayout.ScrollAnimation;
23 | import zone.com.zrefreshlayout.IHeaderView;
24 | import zone.com.zrefreshlayout.R;
25 | import zone.com.zrefreshlayout.ZRefreshLayout;
26 | import zone.com.zrefreshlayout.utils.ScreenUtils;
27 |
28 | /**
29 | * Created by fuzhipeng on 2017/1/13.
30 | */
31 |
32 | public class WaveHead implements IHeaderView {
33 |
34 | private View rootView;
35 | private ImageView imageView;
36 | private int resourceId;
37 | private static final int ANIMATION_DURATION = 1332 * 2;
38 | private WaveUtils mWaveUtils;
39 |
40 | @Override
41 | public View initView(ZRefreshLayout zRefreshLayout) {
42 | rootView = View.inflate(zRefreshLayout.getContext(), R.layout.header_meterial, null);
43 | //注意inflate那种模式 第一层需要空出去 不然会wrapcontent
44 | LinearLayout ll_main = (LinearLayout) rootView.findViewById(R.id.ll_main);
45 | int[] screenPixs = ScreenUtils.getScreenPix((Activity) zRefreshLayout.getContext());
46 | ll_main.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT
47 | , (int) (screenPixs[1] * 0.2)));
48 | imageView = new ImageView(zRefreshLayout.getContext());
49 | int imageViewHeight2width = (int) (screenPixs[1] * 0.2);
50 | imageView.setLayoutParams(new LinearLayout.LayoutParams(imageViewHeight2width, imageViewHeight2width));
51 | ll_main.addView(imageView);
52 | mWaveUtils = new WaveUtils();
53 | mWaveUtils.wave(zRefreshLayout.getContext(), imageViewHeight2width);
54 | return rootView;
55 | }
56 |
57 | @NonNull
58 | @Override
59 | public View getView() {
60 | return rootView;
61 | }
62 |
63 | @Override
64 | public void onPullingDown(float fraction, float headHeight) {
65 | imageView.setRotationX(90 - fraction * 90);
66 | }
67 |
68 | @Override
69 | public void refreshAble(boolean refreshAble) {
70 |
71 | }
72 |
73 | @Override
74 | public void animateBack(ScrollAnimation scrollAnimation, float fraction, float headHeight, ZRefreshLayout.HeadPin mIScroll) {
75 | if (scrollAnimation == ScrollAnimation.RefreshAble_BackAnimation)
76 | imageView.setRotationX(90 - fraction * 90);
77 | }
78 |
79 | @Override
80 | public boolean interceptAnimateBack(ScrollAnimation scrollAnimation, IScroll iScroll) {
81 | return false;
82 | }
83 |
84 | @Override
85 | public void onRefreshing(float headHeight, boolean isAutoRefresh) {
86 | mWaveUtils.valueAnimator.start();
87 | mWaveUtils.mWaveHelper.start();
88 | }
89 |
90 | @Override
91 | public void onComplete() {
92 | imageView.setRotationX(90);
93 | mWaveUtils.valueAnimator.end();
94 | mWaveUtils.mWaveHelper.cancel();
95 | mWaveUtils.mWaveHelper.setLevelProgress(0F);
96 | }
97 |
98 | @Override
99 | public IHeaderView clone_() {
100 | WaveHead clone = new WaveHead();
101 | clone.resourceId = resourceId;
102 | return clone;
103 | }
104 |
105 |
106 | public int getResourceId() {
107 | return resourceId;
108 | }
109 |
110 | public void setResourceId(int resourceId) {
111 | this.resourceId = resourceId;
112 | }
113 |
114 |
115 | class WaveUtils {
116 |
117 | private WaveHelper mWaveHelper;
118 | private ValueAnimatorProxy valueAnimator = ValueAnimatorProxy.ofFloat(0, 1F)
119 | .setDuration(ANIMATION_DURATION)
120 | .setRepeatCount(ValueAnimator.INFINITE)
121 | .addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
122 | @Override
123 | public void onAnimationUpdate(ValueAnimator animation) {
124 | if (mWaveHelper != null)
125 | mWaveHelper.setLevelProgress((Float) animation.getAnimatedValue());
126 | // log("onAnimationUpdate:" + (Float) animation.getAnimatedValue());
127 | }
128 | });
129 |
130 | private void wave(final Context context, final int imageViewHeight2width) {
131 | if (resourceId == -1)
132 | throw new IllegalStateException("resourceId not be null!");
133 | final Bitmap bt = SampleUtils.load(context, resourceId)
134 | .override(imageViewHeight2width, imageViewHeight2width)
135 | .bitmap();
136 |
137 | final ColorMatrix colorMatrix = new ColorMatrix();
138 | colorMatrix.setSaturation(0);
139 |
140 | final BitmapComposer bitmapComposer = BitmapComposer.newComposition(bt.getWidth(), bt.getHeight(), Bitmap.Config.ARGB_4444);
141 | // Matrix first = new Matrix();
142 | // first.postTranslate(0, -20);
143 | mWaveHelper = new WaveHelper(bt.getWidth(), bt.getHeight(), new WaveHelper.RefreshCallback() {
144 | @Override
145 | public void refresh(Bitmap wave) {
146 | Bitmap render = bitmapComposer.clear()
147 | .newLayer(
148 | BitmapComposer.Layer.bitmap(bt)
149 | .colorFilter(new ColorMatrixColorFilter(colorMatrix))
150 | ).newLayer(
151 | BitmapComposer.Layer.bitmap(bt)
152 | .mask(wave, PorterDuff.Mode.DST_IN)
153 | // .matrix(first)
154 | ).render();
155 | imageView.setImageBitmap(render);
156 | }
157 | });
158 | mWaveHelper.cancel();
159 | mWaveHelper.setAmplitude(imageViewHeight2width / 16);
160 | mWaveHelper.setLength(imageViewHeight2width / 1.2F);
161 | mWaveHelper.setSpeed(imageViewHeight2width * 1.2F);
162 | mWaveHelper.setLevelProgress(0F);
163 | }
164 |
165 |
166 | }
167 | }
168 |
--------------------------------------------------------------------------------
/app/src/main/java/zone/com/zrefreshlayoutdemo/resistance/Damping2Head8per.kt:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayoutdemo.resistance
2 |
3 | import zone.com.zrefreshlayout.IResistance
4 |
5 | /**
6 | * Created by fuzhipeng on 2017/1/10.
7 | */
8 |
9 | class Damping2Head8per : IResistance {
10 |
11 | override fun clone_(): IResistance {
12 | return Damping2Head8per()
13 | }
14 |
15 | override fun getOffSetYMapValue(headerHeight: Int, offset: Int): Int {
16 | return if (offset / 2 <= headerHeight * 0.8) offset / 2 else (headerHeight * 0.8).toInt()
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/app/src/main/java/zone/com/zrefreshlayoutdemo/utils/RecyclerViewEmptyUtils.java:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayoutdemo.utils;
2 |
3 | import androidx.annotation.LayoutRes;
4 | import androidx.annotation.NonNull;
5 | import androidx.recyclerview.widget.RecyclerView;
6 | import android.util.Log;
7 | import android.view.View;
8 |
9 | import zone.com.zrefreshlayout.ZRefreshLayout;
10 |
11 | /**
12 | * [2017] by Zone
13 | */
14 |
15 | public class RecyclerViewEmptyUtils {
16 |
17 | private View emptyView;
18 | private RecyclerView rv;
19 |
20 | public static void addEmptyView(RecyclerView rv, @NonNull View emptyView) {
21 | RecyclerViewEmptyUtils recyclerViewEmptyUtils = new RecyclerViewEmptyUtils();
22 | recyclerViewEmptyUtils.addEmptyViewInner(rv, emptyView);
23 | }
24 |
25 | public static void addEmptyView(RecyclerView rv, @LayoutRes int layoutID) {
26 | RecyclerViewEmptyUtils recyclerViewEmptyUtils = new RecyclerViewEmptyUtils();
27 | recyclerViewEmptyUtils.addEmptyViewInner(rv, View.inflate(rv.getContext(), layoutID, null));
28 | }
29 |
30 | private void addEmptyViewInner(final RecyclerView rv, @NonNull final View emptyView) {
31 | RecyclerView.Adapter adapter = rv.getAdapter();
32 | if (adapter == null)
33 | throw new IllegalStateException("oldAdapter 不能为Null!");
34 | this.emptyView = emptyView;
35 | this.rv = rv;
36 | try {
37 | adapter.unregisterAdapterDataObserver(observer);
38 | } catch (Exception e) {
39 | }
40 | if (rv.getParent() instanceof ZRefreshLayout) {
41 | ZRefreshLayout parent = (ZRefreshLayout) rv.getParent();
42 | parent.addView(emptyView, 1);
43 | } else
44 | throw new IllegalStateException("rv parent 类型必须是ZRefreshLayout!");
45 | adapter.registerAdapterDataObserver(observer);
46 | checkIfEmpty();
47 | }
48 |
49 | // private void replaceView(RecyclerView rv, @NonNull View emptyView) {
50 | // ViewGroup parent = (ViewGroup) rv.getParent();
51 | // FrameLayout frameLayout = new FrameLayout(rv.getContext());
52 | // frameLayout.setLayoutParams(rv.getLayoutParams());
53 | // int index = parent.indexOfChild(rv);
54 | //
55 | // parent.removeView(rv);
56 | // frameLayout.addView(rv);
57 | // frameLayout.addView(emptyView);
58 | // parent.addView(frameLayout, index);
59 | // }
60 |
61 |
62 | private RecyclerView.AdapterDataObserver observer = new RecyclerView.AdapterDataObserver() {
63 | public String TAG = "RecyclerViewUtils";
64 |
65 | @Override
66 | public void onChanged() {
67 | checkIfEmpty();
68 | }
69 |
70 | @Override
71 | public void onItemRangeInserted(int positionStart, int itemCount) {
72 | Log.i(TAG, "onItemRangeInserted" + itemCount);
73 | checkIfEmpty();
74 | }
75 |
76 | @Override
77 | public void onItemRangeRemoved(int positionStart, int itemCount) {
78 | checkIfEmpty();
79 | }
80 | };
81 |
82 |
83 | private void checkIfEmpty() {
84 | boolean emptyViewVisible =
85 | rv.getAdapter().getItemCount() == 0;
86 | emptyView.setVisibility(emptyViewVisible ? View.VISIBLE : View.GONE);
87 | }
88 |
89 | }
90 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/aaaaaaaaaaaab.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luhaoaimama1/ZRefreshLayout/1226a2d020b718687865b369810d069328e547cb/app/src/main/res/drawable-xxhdpi/aaaaaaaaaaaab.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/img_header.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luhaoaimama1/ZRefreshLayout/1226a2d020b718687865b369810d069328e547cb/app/src/main/res/drawable-xxhdpi/img_header.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/wave.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luhaoaimama1/ZRefreshLayout/1226a2d020b718687865b369810d069328e547cb/app/src/main/res/drawable-xxhdpi/wave.png
--------------------------------------------------------------------------------
/app/src/main/res/layout/a_circle.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
21 |
22 |
29 |
30 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/a_flexibility.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
12 |
13 |
17 |
18 |
22 |
23 |
24 |
25 |
26 |
27 |
33 |
34 |
35 |
39 |
40 |
47 |
48 |
55 |
56 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/a_scroll_recycler_nest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
14 |
15 |
22 |
25 |
33 |
34 |
40 |
41 |
42 |
43 |
49 |
50 |
56 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/a_setting.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
10 |
11 |
20 |
21 |
26 |
27 |
34 |
35 |
41 |
42 |
49 |
50 |
57 |
58 |
65 |
66 |
67 |
68 |
73 |
74 |
81 |
82 |
87 |
88 |
95 |
96 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
116 |
117 |
130 |
131 |
144 |
145 |
146 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/auto_refresh.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/grid.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_rc_textview.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
14 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/main.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
16 |
17 |
18 |
22 |
23 |
30 |
31 |
36 |
37 |
44 |
45 |
49 |
50 |
54 |
55 |
59 |
60 |
64 |
65 |
69 |
70 |
74 |
75 |
80 |
81 |
89 |
90 |
94 |
95 |
99 |
100 |
104 |
105 |
109 |
110 |
114 |
115 |
120 |
121 |
129 |
130 |
134 |
135 |
139 |
140 |
144 |
145 |
149 |
150 |
151 |
159 |
160 |
161 |
165 |
166 |
167 |
171 |
172 |
176 |
177 |
178 |
179 |
180 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/rev.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/scroller.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
11 |
12 |
16 |
17 |
25 |
26 |
34 |
35 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/text.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/title.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/unique_feature.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/unique_feature_copy.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
13 |
14 |
23 |
24 |
29 |
30 |
43 |
44 |
48 |
49 |
62 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/web.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luhaoaimama1/ZRefreshLayout/1226a2d020b718687865b369810d069328e547cb/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luhaoaimama1/ZRefreshLayout/1226a2d020b718687865b369810d069328e547cb/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luhaoaimama1/ZRefreshLayout/1226a2d020b718687865b369810d069328e547cb/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luhaoaimama1/ZRefreshLayout/1226a2d020b718687865b369810d069328e547cb/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luhaoaimama1/ZRefreshLayout/1226a2d020b718687865b369810d069328e547cb/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #ff4081
6 | #bedbff
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | ZRefreshLayout
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
17 |
18 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/network_security_config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ww1.sinaimg.cn
5 | luhaoaimama1.github.io
6 |
7 |
--------------------------------------------------------------------------------
/app/src/test/java/zone/com/zrefreshlayoutdemo/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayoutdemo;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | ext.kotlin_version = '1.3.0'
5 | // ext.kotlin_version = '1.2.51'
6 | repositories {
7 | jcenter()
8 | mavenCentral()
9 | google()
10 | }
11 | dependencies {
12 | classpath 'com.android.tools.build:gradle:3.3.2'
13 | classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
14 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
15 |
16 | //kotlin 生成文档
17 | classpath 'org.jetbrains.dokka:dokka-gradle-plugin:0.10.0'
18 | // NOTE: Do not place your application dependencies here; they belong
19 | // in the individual module build.gradle files
20 | }
21 | }
22 |
23 | allprojects {
24 | repositories {
25 | maven { url "https://jitpack.io" }
26 | maven { url "https://dl.google.com/dl/android/maven2" }
27 | jcenter()
28 | mavenCentral()
29 | google()
30 | }
31 | }
32 |
33 | task clean(type: Delete) {
34 | delete rootProject.buildDir
35 | }
36 |
--------------------------------------------------------------------------------
/demo/home.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luhaoaimama1/ZRefreshLayout/1226a2d020b718687865b369810d069328e547cb/demo/home.png
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | android.enableJetifier=true
13 | android.useAndroidX=true
14 | org.gradle.jvmargs=-Xmx1536m
15 |
16 | # When configured, Gradle will run in incubating parallel mode.
17 | # This option should only be used with decoupled projects. More details, visit
18 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
19 | # org.gradle.parallel=true
20 | android.injected.testOnly=false
21 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luhaoaimama1/ZRefreshLayout/1226a2d020b718687865b369810d069328e547cb/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Jan 03 10:17:22 CST 2020
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | #distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip
7 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.1-all.zip
8 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':zrefreshlayout'
2 |
--------------------------------------------------------------------------------
/zrefreshlayout/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/zrefreshlayout/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'kotlin-android'
3 |
4 | // JitPack Maven
5 | apply plugin: 'com.github.dcendents.android-maven'
6 | // Your Group
7 | group = 'com.github.luhaoaimama1'
8 |
9 | android {
10 | compileSdkVersion 28
11 |
12 | defaultConfig {
13 | minSdkVersion 14
14 | // targetSdkVersion 24
15 | versionCode 1
16 | versionName "1.0"
17 |
18 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
19 |
20 | }
21 | buildTypes {
22 | release {
23 | minifyEnabled false
24 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
25 | }
26 | }
27 | compileOptions {
28 | kotlinOptions.freeCompilerArgs += ['-module-name', "zone.com.zrefreshlayout"]
29 | }
30 | }
31 |
32 | dependencies {
33 | api fileTree(include: ['*.jar'], dir: 'libs')
34 | androidTestImplementation('androidx.test.espresso:espresso-core:3.1.0', {
35 | exclude group: 'com.android.support', module: 'support-annotations'
36 | })
37 | testImplementation 'junit:junit:4.12'
38 | compileOnly 'androidx.recyclerview:recyclerview:1.0.0'
39 | api 'com.github.luhaoaimama1:ZAnimate:2.0.2'
40 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
41 | }
42 |
43 | //task makeJar(type: Copy) {
44 | // delete 'build/libs/test.jar' //删除已经存在的jar包
45 | // from('build/intermediates/bundles/release/')//从该目录下加载要打包的文件
46 | // into('build/libs/')//jar包的保存目录
47 | // include('classes.jar')//设置过滤,只打包classes文件
48 | // rename('classes.jar', 'test.jar')//重命名,mylibrary.jar 根据自己的需求设置
49 | //}
50 | //
51 | //makeJar.dependsOn(build)
52 |
53 | apply plugin: 'org.jetbrains.dokka'
54 |
55 | //dokka {
56 | // packageOptions {
57 | // prefix = "com.mylib.myannotation"
58 | // suppress = true
59 | // }
60 | //}
61 |
62 | //kotlin 生成文档
63 | task generateSourcesJar(type: Jar) {
64 | group = 'jar'
65 | from android.sourceSets.main.java.srcDirs
66 | classifier = 'sources'
67 | }
68 |
69 | task javadoc(type: Javadoc) {
70 | source = android.sourceSets.main.java.srcDirs
71 | options.encoding = "UTF-8"
72 | classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
73 | }
74 |
75 | task dokkaJavadoc(type: org.jetbrains.dokka.gradle.DokkaTask) {
76 | outputFormat = "javadoc"
77 | outputDirectory = javadoc.destinationDir
78 | }
79 |
80 |
81 | task generateJavadoc(type: Jar, dependsOn: dokkaJavadoc) {
82 | group = 'jar'
83 | classifier = 'javadoc'
84 | from javadoc.destinationDir
85 | }
86 |
87 | artifacts {
88 | archives generateJavadoc
89 | archives generateSourcesJar
90 | }
--------------------------------------------------------------------------------
/zrefreshlayout/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/fuzhipeng/Library/Android/sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/zrefreshlayout/src/androidTest/java/zone/com/zrefreshlayoutdemo/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayoutdemo;
2 |
3 | import android.content.Context;
4 | import androidx.test.platform.app.InstrumentationRegistry;
5 | import androidx.test.ext.junit.runners.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumentation 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() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("zone.com.zrefreshlayout.test", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/zrefreshlayout/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/zrefreshlayout/src/main/java/zone/com/zrefreshlayout/AUtils.kt:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayout
2 |
3 | import android.view.View
4 |
5 | /**
6 | * Created by fuzhipeng on 2017/1/16.
7 | * 头部与footer的处理方法
8 | */
9 | object AUtils {
10 |
11 | @JvmStatic
12 | fun setHeaderHeightToRefresh(zRefreshLayout: ZRefreshLayout, heightToRefresh: Int) {
13 | zRefreshLayout.setHeaderHeightToRefresh(heightToRefresh)
14 | }
15 |
16 | @JvmStatic
17 | fun smoothScrollTo_NotIntercept(iScroll: IScroll, fy: Int) {
18 | iScroll.smoothScrollTo_NotIntercept(fy)
19 | }
20 |
21 | @JvmStatic
22 | fun notityRefreshCompeleStateToRest(iScroll: IScroll) {
23 | iScroll.refreshCompeleStateToRest_AUtils()
24 | }
25 |
26 | /**
27 | * 真正的通知上拉并回调
28 | *
29 | * @param zRefreshLayout
30 | */
31 | @JvmStatic
32 | fun notityLoadMoreListener(zRefreshLayout: ZRefreshLayout) {
33 | zRefreshLayout.notityLoadMoreListener()
34 | }
35 |
36 | @JvmStatic
37 | fun notifyLoadMoreCompleteListener(zRefreshLayout: ZRefreshLayout) {
38 | zRefreshLayout.notifyLoadMoreCompleteListener()
39 | }
40 |
41 | @JvmStatic
42 | fun isRest(zRefreshLayout: ZRefreshLayout): Boolean {
43 | return zRefreshLayout.state == ZRefreshLayout.REST
44 | }
45 |
46 | /**
47 | * 自己处理底部动画,会走fooer的onstart,
48 | * 然后onstart里完成动画
49 | * 通知上啦回调[AUtils.notityLoadMoreListener]
50 | *
51 | * @param zRefreshLayout
52 | */
53 | @JvmStatic
54 | fun loadMore(zRefreshLayout: ZRefreshLayout) {
55 | zRefreshLayout.loadMore()
56 | }
57 |
58 | @JvmStatic
59 | fun getRefreshAbleHeight(zRefreshLayout: ZRefreshLayout): Int = zRefreshLayout.getRefreshAbleHeight()
60 |
61 |
62 | @JvmStatic
63 | fun getContentHeight(zRefreshLayout: ZRefreshLayout): Int=zRefreshLayout.contentHeight
64 |
65 | @JvmStatic
66 | fun getContentView(zRefreshLayout: ZRefreshLayout): View =zRefreshLayout.contentView
67 |
68 |
69 | }
70 |
--------------------------------------------------------------------------------
/zrefreshlayout/src/main/java/zone/com/zrefreshlayout/Config.java:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayout;
2 |
3 | import zone.com.zrefreshlayout.utils.LogUtils;
4 |
5 | /**
6 | * Created by fuzhipeng on 2017/1/11.
7 | */
8 |
9 | public class Config {
10 |
11 | IHeaderView headerView;
12 | IFooterView footerView;
13 | IResistance resistance;
14 | ZRefreshLayout.HeadPin headPin;
15 | boolean isDebug;
16 | ZRefreshLayout.PullListener mPullListener;
17 | ZRefreshLayout.LoadMoreStateRestListener mLoadMoreStateRestListener;
18 | ZRefreshLayout.PullStateRestListener mPullStateRestListener;
19 | ZRefreshLayout.LoadMoreListener mLoadMoreListener;
20 | int delay_millis_auto_complete=10000;
21 |
22 |
23 | private Config() {
24 | }
25 |
26 | public static Config build() {
27 | return new Config();
28 | }
29 |
30 |
31 | public Config setHeader(IHeaderView headerView) {
32 | this.headerView = headerView;
33 | return this;
34 | }
35 |
36 |
37 | public Config setFooter(IFooterView footerView) {
38 | this.footerView = footerView;
39 | return this;
40 | }
41 |
42 | public Config setResistance(IResistance resistance) {
43 | this.resistance = resistance;
44 | return this;
45 | }
46 |
47 | public Config setHeadPin(ZRefreshLayout.HeadPin pinContent) {
48 | this.headPin = pinContent;
49 | return this;
50 | }
51 |
52 | public Config setLoadMoreListener(ZRefreshLayout.LoadMoreListener mLoadMoreListener) {
53 | this.mLoadMoreListener = mLoadMoreListener;
54 | return this;
55 | }
56 | public Config setLoadMoreListener(ZRefreshLayout.LoadMoreListener mLoadMoreListener, ZRefreshLayout.LoadMoreStateRestListener mLoadMoreStateRestListener) {
57 | this.mLoadMoreListener=mLoadMoreListener;
58 | this.mLoadMoreStateRestListener=mLoadMoreStateRestListener;
59 | return this;
60 | }
61 | public Config setPullListener(ZRefreshLayout.PullListener mPullListener) {
62 | this.mPullListener = mPullListener;
63 | return this;
64 | }
65 |
66 | public Config setPullListener(ZRefreshLayout.PullListener mPullListener, ZRefreshLayout.PullStateRestListener mPullStateRestListener) {
67 | this.mPullListener = mPullListener;
68 | this.mPullStateRestListener = mPullStateRestListener;
69 | return this;
70 | }
71 |
72 | public Config writeLog(boolean writeLog) {
73 | this.isDebug = writeLog;
74 | return this;
75 | }
76 | public Config setDelayAutoCompleteTime(int delayAutoComplete) {
77 | this.delay_millis_auto_complete = delayAutoComplete;
78 | return this;
79 | }
80 |
81 |
82 | public void perform() {
83 | ZRefreshLayout.config = this;
84 | LogUtils.isDebug = isDebug;
85 | }
86 |
87 | }
88 |
--------------------------------------------------------------------------------
/zrefreshlayout/src/main/java/zone/com/zrefreshlayout/FlexibilityLayout.kt:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayout
2 |
3 | import android.content.Context
4 | import androidx.core.view.ViewCompat
5 | import android.util.AttributeSet
6 | import zone.com.zrefreshlayout.header.NullHeader
7 | import zone.com.zrefreshlayout.utils.LogUtils.log
8 |
9 | /**
10 | *[2018/12/12] by Zone
11 | */
12 | class FlexibilityLayout : ZRefreshLayout {
13 | constructor(context: Context?) : super(context)
14 | constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
15 | constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
16 |
17 | override fun initHeaderView() {
18 | // super.initHeaderView()
19 | this.mIHeaderView = NullHeader()
20 | headerView = mIHeaderView.initView(this)
21 | }
22 |
23 | override fun setIHeaderView(mIHeaderView: IHeaderView) {
24 | this.mIHeaderView = NullHeader()
25 | super.setIHeaderView(mIHeaderView)
26 | }
27 |
28 |
29 | override fun autoRefresh(haveAnimate: Boolean) {
30 | throw IllegalStateException("不支持刷新")
31 | }
32 |
33 | override fun realMove(dy2: Float) {
34 | var dy=dy2
35 | direction = if (dy > 0) PULL_DOWN
36 | else LOAD_UP
37 |
38 | //dy 需要映射不然 真实的移动 和 MotionEvent移动对不上了 也没法和getRefreshAbleHeight()[真实的]比较了
39 | if (mIResistance != null)
40 | dy = mIResistance.getOffSetYMapValue(refreshAbleHeight, dy.toInt()).toFloat()
41 |
42 | if (state == REST && direction == PULL_DOWN) state = PULL
43 |
44 | if (state == PULL) {
45 | //防止别的状态 可以滚动
46 | mIScroll.scrollTo_(dy.toInt())
47 | }
48 | }
49 |
50 | override fun realCancel() {
51 | if (state == PULL) {
52 | //回弹
53 | mScrollAnimation = ScrollAnimation.DisRefreshAble_BackAnimation
54 | mIScroll.smoothScrollTo_(0)
55 | log("回弹!")
56 | }
57 | }
58 | }
--------------------------------------------------------------------------------
/zrefreshlayout/src/main/java/zone/com/zrefreshlayout/IFooterView.java:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayout;
2 |
3 | import android.view.View;
4 |
5 |
6 | /**
7 | * Created by fuzhipeng on 2017/1/16.
8 | */
9 | public interface IFooterView {
10 | /**
11 | * 全局更换头的配置
12 | * 主要是为了复制头部对象,复制想要复制的属性
13 | * 注意:返回null时候,默认就是LoadFooter了
14 | */
15 | IFooterView clone_();
16 | /**
17 | * 获取footer布局
18 | * @param zRefreshLayout
19 | * @return
20 | */
21 | View getView(ZRefreshLayout zRefreshLayout);
22 |
23 | /**
24 | * loadMore中
25 | * @param footerHeight
26 | */
27 | void onStart(ZRefreshLayout zRefreshLayout, float footerHeight);
28 | /**
29 | * loadMore 结束
30 | */
31 | void onComplete(ZRefreshLayout zRefreshLayout);
32 | }
33 |
--------------------------------------------------------------------------------
/zrefreshlayout/src/main/java/zone/com/zrefreshlayout/IHeaderView.java:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayout;
2 |
3 | import androidx.annotation.NonNull;
4 | import android.view.View;
5 |
6 | /**
7 | * Created by fuzhipeng on 2017/1/16.
8 | */
9 |
10 | public interface IHeaderView {
11 |
12 |
13 | /**
14 | * 获取头部布局
15 | *
16 | * @param zRefreshLayout
17 | * @return
18 | */
19 | View initView(ZRefreshLayout zRefreshLayout);
20 |
21 | @NonNull
22 | View getView();
23 |
24 | /**
25 | * 下拉准备刷新动作
26 | *
27 | * @param fraction 当前下拉高度与头部高度的比 超过头部动画基本保持不变
28 | * @param headHeight
29 | */
30 | void onPullingDown(float fraction, float headHeight);
31 |
32 | /**
33 | * 可刷新与不可刷新 状态切换监听
34 | *
35 | * @param refreshAble
36 | */
37 | void refreshAble(boolean refreshAble);
38 |
39 | /**
40 | * 滚动动画 监听
41 | * @param scrollAnimation 回弹类型
42 | * @param fraction
43 | * @param headHeight
44 | * @param isPinContent
45 | */
46 | void animateBack(ScrollAnimation scrollAnimation, float fraction, float headHeight, ZRefreshLayout.HeadPin isPinContent);
47 |
48 | /**
49 | * 拦截滚动
50 | * 想让其滚动可使用AUtils.smoothScrollTo_NotIntercept(iScroll,0);
51 | * 参考:demo里的 CircleRefresh
52 | *
53 | * @param scrollAnimation
54 | * @param iScroll
55 | * @return
56 | */
57 | boolean interceptAnimateBack(ScrollAnimation scrollAnimation, IScroll iScroll);
58 |
59 | /**
60 | * 刷新进行时
61 | *
62 | * @param headHeight
63 | * @param isAutoRefresh
64 | */
65 | void onRefreshing(float headHeight, boolean isAutoRefresh);
66 |
67 | /**
68 | * 头部Rest前一刻调用此 用来重置状态
69 | */
70 | void onComplete();
71 |
72 | /**
73 | * 全局更换头的配置
74 | * 主要是为了复制头部对象,复制想要复制的属性
75 | * 注意:返回null时候,默认就是新浪头了
76 | */
77 | IHeaderView clone_();
78 |
79 | }
80 |
--------------------------------------------------------------------------------
/zrefreshlayout/src/main/java/zone/com/zrefreshlayout/IResistance.java:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayout;
2 |
3 | /**
4 | * Created by fuzhipeng on 2017/1/10.
5 | */
6 |
7 | public interface IResistance {
8 | /**
9 | * 全局更换头的配置
10 | * 主要是为了复制头部对象,复制想要复制的属性
11 | * 注意:返回null时候,默认就是没有映射了
12 | */
13 | IResistance clone_();
14 |
15 | /**
16 | *
17 | * @param headerHeight
18 | * @param offset 是>0的值
19 | * @return
20 | */
21 | int getOffSetYMapValue(int headerHeight, int offset);
22 | }
23 |
--------------------------------------------------------------------------------
/zrefreshlayout/src/main/java/zone/com/zrefreshlayout/IScroll.java:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayout;
2 |
3 |
4 | import android.view.animation.LinearInterpolator;
5 |
6 | import android.animation.Animator;
7 | import android.animation.ValueAnimator;
8 |
9 | import zone.com.zanimate.value.ValueAnimatorProxy;
10 | import zone.com.zrefreshlayout.utils.SimpleAnimatorListener;
11 |
12 | import static zone.com.zrefreshlayout.utils.LogUtils.log;
13 |
14 | public abstract class IScroll {
15 |
16 | protected ZRefreshLayout mZRefreshLayout;
17 | //当isInterceptRefreshCompeleStateToRest=true的时候代表刷新完成通知由刷新头部动画完成后头部回调
18 | protected boolean isInterceptRefreshCompeleStateToRest =false;
19 |
20 | public IScroll(ZRefreshLayout mZRefreshLayout) {
21 | this.mZRefreshLayout = mZRefreshLayout;
22 | }
23 |
24 | private static final int DEFAULT_DURATION = 250;
25 | private ValueAnimatorProxy valueAnimator = ValueAnimatorProxy.ofInt(0, 100)
26 | .setDuration(DEFAULT_DURATION)
27 | .setInterpolator(new LinearInterpolator())
28 | .addListener(new SimpleAnimatorListener() {
29 |
30 | @Override
31 | public void onAnimationEnd(Animator animation) {
32 | // 到可刷新位置:通知刷新
33 | // 由于AutoRefresh_Animation是下拉就有动画所以通知刷新不在这里
34 | // 仅仅RefreshAble_BackAnimation 通知刷新
35 |
36 | // 归0 :状态恢复操作
37 | // DisRefreshAble_BackAnimation,Complete_BackAnimation
38 | log("onAnimationEnd : Scrolling animation:" + mZRefreshLayout.mScrollAnimation);
39 | if (mZRefreshLayout.mScrollAnimation == ScrollAnimation.RefreshAble_BackAnimation) {
40 | //超过刷新刷新位置 回弹到可刷新位置的动画结束后,后执行刷新动画
41 | mZRefreshLayout.notityRefresh();
42 | }
43 |
44 | if (!isInterceptRefreshCompeleStateToRest &&
45 | mZRefreshLayout.mScrollAnimation == ScrollAnimation.Complete_BackAnimation ||
46 | mZRefreshLayout.mScrollAnimation == ScrollAnimation.DisRefreshAble_BackAnimation) {
47 | refreshCompeleStateToRest();
48 | }
49 |
50 | }
51 | })
52 | .addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
53 | @Override
54 | public void onAnimationUpdate(ValueAnimator animation) {
55 | Integer offset = (Integer) animation.getAnimatedValue();
56 | //主要 监听滚动动画的位置
57 | if (mZRefreshLayout.mIHeaderView != null)
58 | mZRefreshLayout.mIHeaderView.animateBack(mZRefreshLayout.mScrollAnimation,
59 | 1F * Math.abs(getScrollY()) / mZRefreshLayout.getRefreshAbleHeight(),
60 | mZRefreshLayout. getRefreshAbleHeight(), mZRefreshLayout.getHeadPin());
61 | scrollToInner(offset, false);
62 | }
63 |
64 | });
65 |
66 | private void notifyScrollList(Integer offset, boolean isTriggerHeaderOnPullingDown) {
67 |
68 | }
69 |
70 | /**
71 | * 给AUtils调用的需要检测
72 | */
73 | void refreshCompeleStateToRest_AUtils() {
74 | if (mZRefreshLayout.mScrollAnimation == ScrollAnimation.Complete_BackAnimation
75 | || mZRefreshLayout.mScrollAnimation == ScrollAnimation.DisRefreshAble_BackAnimation)
76 | refreshCompeleStateToRest();
77 | else
78 | throw new IllegalStateException("state rest must be Complete_BackAnimation or DisRefreshAble_BackAnimation!");
79 | }
80 |
81 | private void refreshCompeleStateToRest() {
82 | log("State began to reset!");
83 | // if (state == REFRESHING || state == PULL) {
84 | log("Roll back to zero!");
85 | mZRefreshLayout.state = ZRefreshLayout.COMPLETE;
86 | if (mZRefreshLayout.mIHeaderView != null)
87 | mZRefreshLayout.mIHeaderView.onComplete();
88 | mZRefreshLayout.state = ZRefreshLayout.REST;
89 | // if (mPullListener != null && state == REFRESHING) {
90 | if (mZRefreshLayout.mPullStateRestListener != null && mZRefreshLayout.mScrollAnimation == ScrollAnimation.Complete_BackAnimation) {
91 | log("mPullListener.refreshStateRestComplete");
92 | mZRefreshLayout.mPullStateRestListener.refreshStateRestComplete(mZRefreshLayout);
93 | }
94 | mZRefreshLayout.mScrollAnimation = ScrollAnimation.None;
95 | mZRefreshLayout.haveDownEvent = false;
96 | log("State is reset!");
97 | }
98 |
99 | protected void smoothScrollTo_(int fy) {
100 | //拦截滚动动画
101 | if (mZRefreshLayout.mIHeaderView.interceptAnimateBack(mZRefreshLayout.mScrollAnimation, IScroll.this)){
102 | isInterceptRefreshCompeleStateToRest =true;
103 | return;
104 | }
105 | isInterceptRefreshCompeleStateToRest =false;
106 | valueAnimator.setIntValues(getScrollY(), fy);
107 | valueAnimator.start();
108 | }
109 |
110 | void smoothScrollTo_NotIntercept(int fy) {
111 | isInterceptRefreshCompeleStateToRest =false;
112 | valueAnimator.setIntValues(getScrollY(), fy);
113 | valueAnimator.start();
114 | }
115 |
116 | /**
117 | * @param fy
118 | */
119 | protected void scrollTo_(int fy) {
120 | int fy1 = fy > 0 ? fy : 0;
121 | scrollToInner(fy1,true);
122 | }
123 |
124 | /**
125 | * @param fy
126 | * @param isTriggerHeaderOnPullingDown 是否不做位置映射
127 | */
128 | protected abstract void scrollTo(int fy, boolean isTriggerHeaderOnPullingDown);
129 |
130 | int scrollFy = 0;
131 |
132 | private void scrollToInner(int fy, boolean isTriggerHeaderOnPullingDown){
133 | scrollFy=fy;
134 | scrollTo(fy, isTriggerHeaderOnPullingDown);
135 | if (mZRefreshLayout.mIScrollList != null) {
136 | for (IScroll iScroll : mZRefreshLayout.mIScrollList) {
137 | iScroll.scrollTo(fy, isTriggerHeaderOnPullingDown);
138 | }
139 | }
140 | };
141 |
142 | protected int getScrollY() {
143 | return scrollFy;
144 | }
145 | }
--------------------------------------------------------------------------------
/zrefreshlayout/src/main/java/zone/com/zrefreshlayout/ScrollAnimation.java:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayout;
2 |
3 | /**
4 | * Created by fuzhipeng on 2017/1/13.
5 | */
6 |
7 | public enum ScrollAnimation {
8 | None,//未回弹 初始状态
9 | AutoRefresh_Animation,//自动刷新 滚动到头部高度
10 | DisRefreshAble_BackAnimation,//未达到刷新 直接回弹0
11 | RefreshAble_BackAnimation,//超过刷新刷新位置 回弹到可刷新位置
12 | Complete_BackAnimation;//完成刷新后回弹
13 | }
14 |
--------------------------------------------------------------------------------
/zrefreshlayout/src/main/java/zone/com/zrefreshlayout/footer/LoadFooter.java:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayout.footer;
2 |
3 | import android.app.Activity;
4 | import android.view.View;
5 | import android.view.ViewGroup;
6 | import android.view.animation.LinearInterpolator;
7 | import android.widget.ImageView;
8 | import android.widget.LinearLayout;
9 |
10 | import android.animation.ValueAnimator;
11 |
12 | import zone.com.zanimate.value.ValueAnimatorProxy;
13 | import zone.com.zrefreshlayout.AUtils;
14 | import zone.com.zrefreshlayout.IFooterView;
15 | import zone.com.zrefreshlayout.R;
16 | import zone.com.zrefreshlayout.ZRefreshLayout;
17 | import zone.com.zrefreshlayout.utils.ScreenUtils;
18 |
19 | /**
20 | * Created by fuzhipeng on 2017/1/10.
21 | */
22 |
23 | public class LoadFooter implements IFooterView {
24 | private View rootView;
25 | private ImageView loadingView;
26 | private ZRefreshLayout zRefreshLayout;
27 |
28 | @Override
29 | public View getView(ZRefreshLayout zRefreshLayout) {
30 | this.zRefreshLayout=zRefreshLayout;
31 | rootView= View.inflate(zRefreshLayout.getContext(), R.layout.footer, null);
32 | loadingView = (ImageView) rootView.findViewById(R.id.iv_loading);
33 | int[] screenPixs = ScreenUtils.getScreenPix((Activity) zRefreshLayout.getContext());
34 | rootView.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT
35 | , (int) (screenPixs[1] * 0.1)));
36 |
37 | ViewGroup.LayoutParams loadingViewLp = loadingView.getLayoutParams();
38 | loadingViewLp.width = (int) (screenPixs[1] * 0.05);
39 | loadingViewLp.height =(int) (screenPixs[1] * 0.05);
40 | loadingView.setLayoutParams(loadingViewLp);
41 | return rootView;
42 | }
43 |
44 | @Override
45 | public void onStart(ZRefreshLayout zRefreshLayout, float footerHeight) {
46 | loadingView.setVisibility(View.VISIBLE);
47 | valueAnimator.start();
48 | AUtils.notityLoadMoreListener(zRefreshLayout);
49 | }
50 |
51 | @Override
52 | public void onComplete(ZRefreshLayout zRefreshLayout) {
53 | if(valueAnimator.isRunning())
54 | valueAnimator.end();
55 | loadingView.setVisibility(View.INVISIBLE);
56 | AUtils.notifyLoadMoreCompleteListener(zRefreshLayout);
57 | }
58 |
59 | private ValueAnimatorProxy valueAnimator = ValueAnimatorProxy.ofInt(0, 360)
60 | .setDuration(1200)
61 | .setInterpolator(new LinearInterpolator())
62 | .setRepeatCount(ValueAnimator.INFINITE)
63 | .addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
64 | @Override
65 | public void onAnimationUpdate(ValueAnimator animation) {
66 | // 30 =360/12;
67 | // ZRefreshLayout.log("animation.getAnimatedValue():"+animation.getAnimatedValue()+"——————进度:"+((Integer) animation.getAnimatedValue()/30)*30F);
68 | loadingView.setRotation(((Integer) animation.getAnimatedValue()/30)*30F);
69 | }
70 | });
71 | @Override
72 | public IFooterView clone_() {
73 | LoadFooter clone =new LoadFooter();
74 | return clone;
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/zrefreshlayout/src/main/java/zone/com/zrefreshlayout/footer/MeterialFooter.java:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayout.footer;
2 |
3 | import android.app.Activity;
4 | import android.view.View;
5 | import android.view.ViewGroup;
6 | import android.widget.LinearLayout;
7 |
8 | import zone.com.zrefreshlayout.AUtils;
9 | import zone.com.zrefreshlayout.IFooterView;
10 | import zone.com.zrefreshlayout.R;
11 | import zone.com.zrefreshlayout.ZRefreshLayout;
12 | import zone.com.zrefreshlayout.utils.ScreenUtils;
13 | import zone.com.zrefreshlayout.v4.MeterialCircle;
14 |
15 | /**
16 | * Created by fuzhipeng on 2017/1/10.
17 | */
18 |
19 | public class MeterialFooter implements IFooterView {
20 | private MeterialCircle mMeterialCircle;
21 | private ViewGroup rootView;
22 |
23 | @Override
24 | public View getView(ZRefreshLayout zRefreshLayout) {
25 | rootView = (ViewGroup) View.inflate(zRefreshLayout.getContext(), R.layout.header_meterial, null);
26 | //注意inflate那种模式 第一层需要空出去 不然会wrapcontent
27 | LinearLayout ll_main = (LinearLayout) rootView.findViewById(R.id.ll_main);
28 | int[] screenPixs = ScreenUtils.getScreenPix((Activity) zRefreshLayout.getContext());
29 | ll_main.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT
30 | , (int) (screenPixs[1] * 0.1)));
31 | mMeterialCircle=new MeterialCircle(ll_main,(int) (screenPixs[1] * 0.065));
32 | rootView.addView(mMeterialCircle.getView());
33 | rootView.setVisibility(View.INVISIBLE);
34 | return rootView;
35 | }
36 |
37 | @Override
38 | public void onStart(ZRefreshLayout zRefreshLayout, float footerHeight) {
39 | rootView.setVisibility(View.VISIBLE);
40 | mMeterialCircle.start();
41 | AUtils.notityLoadMoreListener(zRefreshLayout);
42 | }
43 |
44 | @Override
45 | public void onComplete(ZRefreshLayout zRefreshLayout) {
46 | rootView.setVisibility(View.INVISIBLE);
47 | mMeterialCircle.reset();
48 | AUtils.notifyLoadMoreCompleteListener(zRefreshLayout);
49 |
50 | }
51 | @Override
52 | public IFooterView clone_() {
53 | MeterialFooter clone =new MeterialFooter();
54 | return clone;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/zrefreshlayout/src/main/java/zone/com/zrefreshlayout/footer/NullFooter.java:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayout.footer;
2 |
3 | import android.view.View;
4 |
5 | import zone.com.zrefreshlayout.AUtils;
6 | import zone.com.zrefreshlayout.IFooterView;
7 | import zone.com.zrefreshlayout.ZRefreshLayout;
8 | import zone.com.zrefreshlayout.utils.LogUtils;
9 |
10 | /**
11 | * Created by fuzhipeng on 2017/1/10.
12 | */
13 |
14 | public class NullFooter implements IFooterView {
15 | private View rootView;
16 |
17 | @Override
18 | public View getView(ZRefreshLayout zRefreshLayout) {
19 | rootView= new View(zRefreshLayout.getContext());
20 | return rootView;
21 | }
22 |
23 | @Override
24 | public void onStart(ZRefreshLayout zRefreshLayout, float footerHeight) {
25 | LogUtils.log(" AUtils.notityLoadMoreListener(zRefreshLayout);");
26 | AUtils.notityLoadMoreListener(zRefreshLayout);
27 | }
28 |
29 | @Override
30 | public void onComplete(ZRefreshLayout zRefreshLayout) {
31 | AUtils.notifyLoadMoreCompleteListener(zRefreshLayout);
32 | }
33 |
34 | @Override
35 | public IFooterView clone_() {
36 | NullFooter clone =new NullFooter();
37 | return clone;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/zrefreshlayout/src/main/java/zone/com/zrefreshlayout/header/MeterialHead.java:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayout.header;
2 |
3 | import android.app.Activity;
4 | import androidx.annotation.NonNull;
5 | import android.view.View;
6 | import android.widget.FrameLayout;
7 |
8 | import zone.com.zrefreshlayout.AUtils;
9 | import zone.com.zrefreshlayout.IScroll;
10 | import zone.com.zrefreshlayout.ScrollAnimation;
11 | import zone.com.zrefreshlayout.IHeaderView;
12 | import zone.com.zrefreshlayout.ZRefreshLayout;
13 | import zone.com.zrefreshlayout.utils.LogUtils;
14 | import zone.com.zrefreshlayout.utils.ScreenUtils;
15 | import zone.com.zrefreshlayout.v4.MeterialCircle;
16 |
17 | /**
18 | * Created by fuzhipeng on 2017/1/12.
19 | */
20 |
21 | public class MeterialHead implements IHeaderView {
22 | private int[] colors;
23 | private MeterialCircle mMeterialCircle;
24 | private ZRefreshLayout zRefreshLayout;
25 |
26 | public MeterialHead(int[] colors) {
27 | this.colors = colors;
28 | }
29 | public MeterialHead() {
30 | }
31 |
32 | @Override
33 | public IHeaderView clone_() {
34 | return new MeterialHead(colors);
35 | }
36 |
37 | @Override
38 | public View initView(ZRefreshLayout zRefreshLayout) {
39 | this.zRefreshLayout = zRefreshLayout;
40 | int[] screenPixs = ScreenUtils.getScreenPix((Activity) zRefreshLayout.getContext());
41 | mMeterialCircle = new MeterialCircle(zRefreshLayout, (int) (screenPixs[1] * 0.065));
42 | if(colors!=null)
43 | mMeterialCircle.setColorSchemeColors(colors);
44 | AUtils.setHeaderHeightToRefresh(zRefreshLayout,(int) (screenPixs[1] * 0.065*2.0));
45 | FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mMeterialCircle.getView().getLayoutParams();
46 | lp.bottomMargin= (int) (screenPixs[1] * 0.065/2);
47 | mMeterialCircle.getView().setLayoutParams(lp);
48 | return mMeterialCircle.getView();
49 | }
50 |
51 | @NonNull
52 | @Override
53 | public View getView() {
54 | return mMeterialCircle.getView();
55 | }
56 |
57 |
58 | @Override
59 | public void onPullingDown(float fraction, float headHeight) {
60 | mMeterialCircle.pullProgress(fraction);
61 | }
62 |
63 | @Override
64 | public void refreshAble(boolean refreshAble) {
65 |
66 | }
67 |
68 | @Override
69 | public void animateBack(ScrollAnimation scrollAnimation, float fraction, float headHeight, ZRefreshLayout.HeadPin isPinContent) {
70 | }
71 |
72 | @Override
73 | public boolean interceptAnimateBack(ScrollAnimation scrollAnimation, final IScroll iScroll) {
74 | if (zRefreshLayout.getHeadPin()== ZRefreshLayout.HeadPin.PIN && scrollAnimation == ScrollAnimation.Complete_BackAnimation) {
75 | mMeterialCircle.startScaleDownAnimation(new MeterialCircle.ScaleDownCallback() {
76 | @Override
77 | public void over() {
78 | log("over()");
79 | AUtils.notityRefreshCompeleStateToRest(iScroll);
80 | }
81 | });
82 | return true;
83 | }
84 | return false;
85 | }
86 |
87 | @Override
88 | public void onRefreshing(float headHeight, boolean isAutoRefresh) {
89 | if (isAutoRefresh) {
90 | log("startScaleUpAnimation");
91 | // mMeterialCircle.startScaleUpAnimation();
92 | }
93 | log("mProgress.start()");
94 | mMeterialCircle.start();
95 | log("onRefreshing");
96 | }
97 |
98 | @Override
99 | public void onComplete() {
100 | mMeterialCircle.reset();
101 | mMeterialCircle.getView().setTranslationY(0);//众神归位
102 | log("mProgress.reset()");
103 | log("onComplete");
104 | }
105 |
106 | private void log(String log) {
107 | LogUtils.log("MeterialHead Log:"+log);
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/zrefreshlayout/src/main/java/zone/com/zrefreshlayout/header/NullHeader.kt:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayout.header
2 |
3 | import android.view.View
4 | import zone.com.zrefreshlayout.IHeaderView
5 | import zone.com.zrefreshlayout.IScroll
6 | import zone.com.zrefreshlayout.ScrollAnimation
7 | import zone.com.zrefreshlayout.ZRefreshLayout
8 |
9 | /**
10 | *[2018/12/12] by Zone
11 | */
12 |
13 | class NullHeader : IHeaderView {
14 |
15 | private lateinit var rootView: View
16 |
17 | override fun getView(): View = rootView
18 |
19 | override fun initView(zRefreshLayout: ZRefreshLayout): View {
20 | rootView = View(zRefreshLayout.context)
21 | return rootView
22 | }
23 |
24 | override fun interceptAnimateBack(scrollAnimation: ScrollAnimation?, iScroll: IScroll?): Boolean =
25 | false
26 |
27 | override fun clone_(): IHeaderView = NullHeader()
28 |
29 | override fun onPullingDown(fraction: Float, headHeight: Float) {
30 | }
31 |
32 | override fun refreshAble(refreshAble: Boolean) {
33 | }
34 |
35 | override fun animateBack(scrollAnimation: ScrollAnimation?, fraction: Float, headHeight: Float, isPinContent: ZRefreshLayout.HeadPin) {
36 | }
37 |
38 | override fun onRefreshing(headHeight: Float, isAutoRefresh: Boolean) {
39 | }
40 |
41 | override fun onComplete() {
42 | }
43 |
44 |
45 | }
--------------------------------------------------------------------------------
/zrefreshlayout/src/main/java/zone/com/zrefreshlayout/header/SinaRefreshHeader.java:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayout.header;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import androidx.annotation.DrawableRes;
6 | import androidx.annotation.NonNull;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 | import android.view.animation.LinearInterpolator;
11 | import android.widget.ImageView;
12 | import android.widget.LinearLayout;
13 | import android.widget.TextView;
14 |
15 | import android.animation.ValueAnimator;
16 |
17 | import zone.com.zanimate.value.ValueAnimatorProxy;
18 | import zone.com.zrefreshlayout.IScroll;
19 | import zone.com.zrefreshlayout.ScrollAnimation;
20 | import zone.com.zrefreshlayout.IHeaderView;
21 | import zone.com.zrefreshlayout.R;
22 | import zone.com.zrefreshlayout.ZRefreshLayout;
23 | import zone.com.zrefreshlayout.utils.DensityUtils;
24 | import zone.com.zrefreshlayout.utils.LogUtils;
25 | import zone.com.zrefreshlayout.utils.ScreenUtils;
26 |
27 | /**
28 | * Created by lcodecore on 2016/10/2.
29 | */
30 |
31 | public class SinaRefreshHeader implements IHeaderView {
32 |
33 | private ImageView refreshArrow;
34 | private ImageView loadingView;
35 | private TextView refreshTextView;
36 | private View rootView;
37 | private LinearLayout ll_main;
38 |
39 | public void setArrowResource(@DrawableRes int resId) {
40 | refreshArrow.setImageResource(resId);
41 | }
42 |
43 | public void setPullDownStr(String pullDownStr1) {
44 | pullDownStr = pullDownStr1;
45 | }
46 |
47 | public void setReleaseRefreshStr(String releaseRefreshStr1) {
48 | releaseRefreshStr = releaseRefreshStr1;
49 | }
50 |
51 | public void setRefreshingStr(String refreshingStr1) {
52 | refreshingStr = refreshingStr1;
53 | }
54 |
55 | private String pullDownStr = "下拉刷新";
56 | private String releaseRefreshStr = "释放刷新";
57 | private String refreshingStr = "正在刷新";
58 |
59 | @Override
60 | public IHeaderView clone_() {
61 | SinaRefreshHeader clone = new SinaRefreshHeader();
62 | return clone;
63 | }
64 |
65 | @Override
66 | public View initView(ZRefreshLayout zRefreshLayout) {
67 | rootView = LayoutInflater.from(zRefreshLayout.getContext()).inflate(R.layout.view_sinaheader,zRefreshLayout,false);
68 | //注意inflate那种模式 第一层需要空出去 不然会wrapcontent
69 | ll_main = (LinearLayout) rootView.findViewById(R.id.ll_main);
70 | refreshArrow = (ImageView) rootView.findViewById(R.id.iv_arrow);
71 | refreshTextView = (TextView) rootView.findViewById(R.id.tv);
72 | loadingView = (ImageView) rootView.findViewById(R.id.iv_loading);
73 | screenAdapter(zRefreshLayout,zRefreshLayout.getContext());
74 | return rootView;
75 | }
76 |
77 | @NonNull
78 | @Override
79 | public View getView() {
80 | return rootView;
81 | }
82 |
83 | private void screenAdapter(ZRefreshLayout zRefreshLayout, Context context) {
84 | int[] screenPixs = ScreenUtils.getScreenPix((Activity) context);
85 | ll_main.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT
86 | , (int) (screenPixs[1] * 0.1)));
87 | ViewGroup.LayoutParams refreshArrowLp = refreshArrow.getLayoutParams();
88 | refreshArrowLp.width = getAnInt(71, screenPixs, true);
89 | refreshArrowLp.height = getAnInt(71, screenPixs, false);
90 | refreshArrow.setLayoutParams(refreshArrowLp);
91 | ViewGroup.LayoutParams loadingViewLp = loadingView.getLayoutParams();
92 | loadingViewLp.width = getAnInt(71, screenPixs, true);
93 | loadingViewLp.height = getAnInt(71, screenPixs, false);
94 | loadingView.setLayoutParams(loadingViewLp);
95 | //注意TextSiz 要的是sp 需要px转过去
96 | refreshTextView.setTextSize(DensityUtils.px2sp(context, getAnInt(35, screenPixs, true)));
97 | }
98 |
99 | //我的参考图是1080*1920
100 | private int getAnInt(int dx, int[] screenPixs, boolean isWidth) {
101 | if (isWidth)
102 | return (int) (1F * dx / 1080 * screenPixs[0]);
103 | else
104 | return (int) (1F * dx / 1920 * screenPixs[1]);
105 | }
106 |
107 | @Override
108 | public void onPullingDown(float fraction, float headHeight) {
109 | }
110 |
111 | @Override
112 | public void refreshAble(boolean refreshAble) {
113 | if (refreshAble) {
114 | refreshArrow.animate().rotation(-180).start();
115 | refreshTextView.setText(releaseRefreshStr);
116 | } else {
117 | refreshTextView.setText(pullDownStr);
118 | refreshArrow.animate().rotation(0).start();
119 | }
120 | }
121 |
122 | @Override
123 | public void animateBack(ScrollAnimation scrollAnimation, float fraction, float headHeight,
124 | ZRefreshLayout.HeadPin mIScroll) {
125 | }
126 |
127 | @Override
128 | public boolean interceptAnimateBack(ScrollAnimation scrollAnimation, IScroll iScroll) {
129 | return false;
130 | }
131 |
132 | @Override
133 | public void onRefreshing(float headHeight, boolean isAutoRefresh) {
134 | refreshTextView.setText(refreshingStr);
135 | refreshArrow.setVisibility(View.GONE);
136 | loadingView.setVisibility(View.VISIBLE);
137 | valueAnimator.start();
138 | log("onRefreshing");
139 | }
140 |
141 | private ValueAnimatorProxy valueAnimator = ValueAnimatorProxy.ofInt(0, 360)
142 | .setDuration(1200)
143 | .setInterpolator(new LinearInterpolator())
144 | .setRepeatCount(ValueAnimator.INFINITE)
145 | .addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
146 | @Override
147 | public void onAnimationUpdate(ValueAnimator animation) {
148 | // 30 =360/12;
149 | // ZRefreshLayout.log("animation.getAnimatedValue():"+animation.getAnimatedValue()+"——————进度:"+((Integer) animation.getAnimatedValue()/30)*30F);
150 | loadingView.setRotation(((Integer) animation.getAnimatedValue() / 30) * 30F);
151 | }
152 | });
153 |
154 | @Override
155 | public void onComplete() {
156 | refreshArrow.setVisibility(View.VISIBLE);
157 | loadingView.setVisibility(View.GONE);
158 | if (valueAnimator.isRunning())
159 | valueAnimator.end();
160 | log("onComplete");
161 | }
162 |
163 | private void log(String log) {
164 | LogUtils.log("SinaRefreshHeader Log:"+log);
165 | }
166 |
167 | }
168 |
--------------------------------------------------------------------------------
/zrefreshlayout/src/main/java/zone/com/zrefreshlayout/loadmore/ListViewLoadMoreListener.java:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayout.loadmore;
2 |
3 | import android.view.View;
4 | import android.widget.AbsListView;
5 | import android.widget.ListAdapter;
6 | import android.widget.ListView;
7 |
8 | import zone.com.zrefreshlayout.AUtils;
9 | import zone.com.zrefreshlayout.ZRefreshLayout;
10 |
11 | import static zone.com.zrefreshlayout.utils.LogUtils.log;
12 |
13 | /**
14 | * [2017] by Zone
15 | */
16 |
17 | public class ListViewLoadMoreListener implements LoadMoreOtherListener {
18 |
19 | private ZRefreshLayout zRefreshLayout;
20 | private OnScrollListViewListener mOnScrollRecyclerViewListener;
21 |
22 | @Override
23 | public void addListener(View view, ZRefreshLayout zRefreshLayout) {
24 | ListView rv = (ListView) view;
25 | this.zRefreshLayout = zRefreshLayout;
26 | rv.setOnScrollListener(mOnScrollRecyclerViewListener = new OnScrollListViewListener());
27 | }
28 |
29 | @Override
30 | public void removeListener(View view) {
31 | ListView rv = (ListView) view;
32 | rv.setOnScrollListener(null);
33 | }
34 |
35 | @Override
36 | public boolean haveListener() {
37 | return mOnScrollRecyclerViewListener != null;
38 | }
39 |
40 | @Override
41 | public boolean instanceOf(View view) {
42 | return view instanceof ListView;
43 | }
44 |
45 | @Override
46 | public LoadMoreOtherListener clone_() {
47 | return new ListViewLoadMoreListener();
48 | }
49 |
50 |
51 | public class OnScrollListViewListener implements AbsListView.OnScrollListener {
52 |
53 |
54 | @Override
55 | public void onScrollStateChanged(AbsListView view, int scrollState) {
56 | if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE)
57 | if (!isFirstItemVisible(view) && zRefreshLayout.isCanLoadMore()
58 | && AUtils.isRest(zRefreshLayout) && isLastItemVisible(view)) {
59 | log("ListViewLoadMoreListener---->loadMore");
60 | AUtils.loadMore(zRefreshLayout);// 执行上拉加载数据
61 | }
62 | }
63 |
64 | /**
65 | * 判断最后一个条目是否完全可见
66 | *
67 | * @param view
68 | * @return
69 | */
70 | private boolean isLastItemVisible(AbsListView view) {
71 | ListAdapter adapter = view.getAdapter();
72 | // 如果未设置Adapter或者Adapter没有数据可以上拉刷新
73 | if (null == adapter || adapter.getCount() == 0) {
74 | return true;
75 | }
76 | // 最后一个条目View完全展示,可以刷新
77 | int lastVisiblePosition = view.getLastVisiblePosition();
78 | if (lastVisiblePosition >= adapter.getCount() - 1) {
79 | return view.getChildAt(view.getChildCount() - 1).getBottom()
80 | <= view.getBottom();
81 | }
82 | return false;
83 | }
84 |
85 | private boolean isFirstItemVisible(AbsListView view) {
86 | ListAdapter adapter = view.getAdapter();
87 | if (null == adapter || adapter.getCount() == 0)
88 | return true;
89 | if (view.getFirstVisiblePosition() == 0)
90 | return view.getChildAt(0).getTop() >= 0;
91 | return false;
92 | }
93 |
94 | @Override
95 | public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
96 |
97 | }
98 |
99 |
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/zrefreshlayout/src/main/java/zone/com/zrefreshlayout/loadmore/LoadMoreController.java:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayout.loadmore;
2 |
3 | import android.view.View;
4 |
5 | import java.util.ArrayList;
6 | import java.util.List;
7 |
8 | import zone.com.zrefreshlayout.ZRefreshLayout;
9 |
10 | /**
11 | * [2017] by Zone
12 | */
13 |
14 | public class LoadMoreController {
15 |
16 | private static List list = new ArrayList<>();
17 |
18 | static {
19 | list.add(new RecyclerViewLoadMoreListener());
20 | list.add(new ListViewLoadMoreListener());
21 | }
22 |
23 | public static LoadMoreOtherListener addLoadMoreListener(View view, ZRefreshLayout zRefreshLayout) {
24 | LoadMoreOtherListener result = null;
25 | for (LoadMoreOtherListener loadMoreListener : list) {
26 | if (loadMoreListener.instanceOf(view)) {
27 | //这里用深克隆 所以不会内存泄漏
28 | result = loadMoreListener.clone_();
29 | result.addListener(view, zRefreshLayout);
30 | break;
31 | }
32 | }
33 | return result;
34 | }
35 |
36 | public static List getList() {
37 | return list;
38 | }
39 |
40 | public static void setList(List list) {
41 | LoadMoreController.list = list;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/zrefreshlayout/src/main/java/zone/com/zrefreshlayout/loadmore/LoadMoreOtherListener.java:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayout.loadmore;
2 |
3 | import android.view.View;
4 |
5 | import zone.com.zrefreshlayout.ZRefreshLayout;
6 |
7 | /**
8 | * [2017] by Zone
9 | */
10 |
11 | public interface LoadMoreOtherListener {
12 |
13 | void addListener(View view, ZRefreshLayout zRefreshLayout);
14 | void removeListener(View view);
15 | boolean haveListener();
16 | boolean instanceOf(View view);
17 | LoadMoreOtherListener clone_();
18 | }
19 |
--------------------------------------------------------------------------------
/zrefreshlayout/src/main/java/zone/com/zrefreshlayout/loadmore/RecyclerViewLoadMoreListener.java:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayout.loadmore;
2 |
3 | import androidx.recyclerview.widget.RecyclerView;
4 | import android.view.View;
5 |
6 | import zone.com.zrefreshlayout.AUtils;
7 | import zone.com.zrefreshlayout.ZRefreshLayout;
8 |
9 | import static zone.com.zrefreshlayout.utils.LogUtils.log;
10 |
11 | /**
12 | * [2017] by Zone
13 | */
14 |
15 | public class RecyclerViewLoadMoreListener implements LoadMoreOtherListener {
16 |
17 | private ZRefreshLayout zRefreshLayout;
18 | private OnScrollRecyclerViewListener mOnScrollRecyclerViewListener;
19 |
20 | @Override
21 | public void addListener(View view,ZRefreshLayout zRefreshLayout) {
22 | RecyclerView rv =(RecyclerView)view;
23 | this.zRefreshLayout=zRefreshLayout;
24 | rv.addOnScrollListener(mOnScrollRecyclerViewListener=new OnScrollRecyclerViewListener());
25 | }
26 |
27 | @Override
28 | public void removeListener(View view) {
29 | RecyclerView rv =(RecyclerView)view;
30 | rv.addOnScrollListener(mOnScrollRecyclerViewListener);
31 | }
32 |
33 | @Override
34 | public boolean haveListener() {
35 | return mOnScrollRecyclerViewListener!=null;
36 | }
37 |
38 | @Override
39 | public boolean instanceOf(View view) {
40 | return view instanceof RecyclerView;
41 | }
42 |
43 | @Override
44 | public LoadMoreOtherListener clone_() {
45 | return new RecyclerViewLoadMoreListener();
46 | }
47 |
48 |
49 | public class OnScrollRecyclerViewListener extends RecyclerView.OnScrollListener {
50 |
51 |
52 | @Override
53 | public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
54 | super.onScrollStateChanged(recyclerView, newState);
55 | // 只有在闲置状态情况下检查
56 | if (newState == RecyclerView.SCROLL_STATE_IDLE) {
57 | // 如果满足允许上拉加载、非加载状态中、最后一个显示的 item 与数据源的大小一样,则表示滑动入底部
58 | if (!isFirstItemVisible(recyclerView) && zRefreshLayout.isCanLoadMore()
59 | && AUtils.isRest(zRefreshLayout) && isLastItemVisible(recyclerView)) {
60 | log("RecyclerViewLoadMoreListener---->loadMore");
61 | AUtils.loadMore(zRefreshLayout);// 执行上拉加载数据
62 |
63 | }
64 | }
65 | }
66 |
67 | @Override
68 | public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
69 | super.onScrolled(recyclerView, dx, dy);
70 | }
71 |
72 | /**
73 | * 判断第一个条目是否完全可见
74 | *
75 | * @param recyclerView
76 | * @return
77 | */
78 | private boolean isFirstItemVisible(RecyclerView recyclerView) {
79 | final RecyclerView.Adapter> adapter = recyclerView.getAdapter();
80 | // 如果未设置Adapter或者Adapter没有数据可以下拉刷新
81 | if (null == adapter || adapter.getItemCount() == 0) {
82 | return true;
83 | }
84 | // 第一个条目完全展示,可以刷新
85 | if (getFirstVisiblePosition(recyclerView) == 0) {
86 | return recyclerView.getChildAt(0).getTop() >=0;
87 | }
88 | return false;
89 | }
90 |
91 | /**
92 | * 获取第一个可见子View的位置下标
93 | *
94 | * @param recyclerView
95 | * @return
96 | */
97 | private int getFirstVisiblePosition(RecyclerView recyclerView) {
98 | View firstVisibleChild = recyclerView.getChildAt(0);
99 | return firstVisibleChild != null ?
100 | recyclerView.getChildAdapterPosition(firstVisibleChild) : -1;
101 | }
102 |
103 | /**
104 | * 判断最后一个条目是否完全可见
105 | *
106 | * @param recyclerView
107 | * @return
108 | */
109 | private boolean isLastItemVisible(RecyclerView recyclerView) {
110 | final RecyclerView.Adapter> adapter = recyclerView.getAdapter();
111 | // 如果未设置Adapter或者Adapter没有数据可以上拉刷新
112 | if (null == adapter || adapter.getItemCount() == 0) {
113 | return true;
114 | }
115 | // 最后一个条目View完全展示,可以刷新
116 | int lastVisiblePosition = getLastVisiblePosition(recyclerView);
117 | if (lastVisiblePosition >= recyclerView.getAdapter().getItemCount() - 1) {
118 | return recyclerView.getChildAt(recyclerView.getChildCount() - 1).getBottom()
119 | <= recyclerView.getBottom();
120 | }
121 | return false;
122 | }
123 |
124 | /**
125 | * 获取最后一个可见子View的位置下标
126 | *
127 | * @param recyclerView
128 | * @return
129 | */
130 | private int getLastVisiblePosition(RecyclerView recyclerView) {
131 | View lastVisibleChild = recyclerView.getChildAt(recyclerView.getChildCount() - 1);
132 | return lastVisibleChild != null ? recyclerView.getChildAdapterPosition(lastVisibleChild) : -1;
133 | }
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/zrefreshlayout/src/main/java/zone/com/zrefreshlayout/resistance/DampingHalf.java:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayout.resistance;
2 |
3 | import zone.com.zrefreshlayout.IResistance;
4 |
5 | /**
6 | * Created by fuzhipeng on 2017/1/10.
7 | */
8 |
9 | public class DampingHalf implements IResistance {
10 |
11 | @Override
12 | public IResistance clone_() {
13 | DampingHalf clone_ = new DampingHalf();
14 | return clone_;
15 | }
16 | @Override
17 | public int getOffSetYMapValue(int headerHeight, int offset) {
18 | return offset/2;
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/zrefreshlayout/src/main/java/zone/com/zrefreshlayout/resistance/DampingHalfToHead.java:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayout.resistance;
2 |
3 | import zone.com.zrefreshlayout.IResistance;
4 |
5 | /**
6 | * Created by fuzhipeng on 2017/1/10.
7 | */
8 |
9 | public class DampingHalfToHead implements IResistance {
10 |
11 | @Override
12 | public IResistance clone_() {
13 | DampingHalfToHead clone_ = new DampingHalfToHead();
14 | return clone_;
15 | }
16 |
17 | @Override
18 | public int getOffSetYMapValue(int headerHeight, int offset) {
19 | return offset / 2 <= headerHeight ? offset / 2 : headerHeight;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/zrefreshlayout/src/main/java/zone/com/zrefreshlayout/resistance/DampingTo3Head.java:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayout.resistance;
2 |
3 | import zone.com.zrefreshlayout.IResistance;
4 |
5 | /**
6 | * Created by fuzhipeng on 2017/1/10.
7 | */
8 |
9 | public class DampingTo3Head implements IResistance {
10 |
11 | @Override
12 | public IResistance clone_() {
13 | DampingTo3Head clone_ = new DampingTo3Head();
14 | return clone_;
15 | }
16 |
17 | @Override
18 | public int getOffSetYMapValue(int headerHeight, int offset) {
19 | return offset <= headerHeight*1.5 ? offset: (int) (headerHeight * 1.5);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/zrefreshlayout/src/main/java/zone/com/zrefreshlayout/scroll/ScrollDoNothing.kt:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayout.scroll
2 |
3 | import zone.com.zrefreshlayout.IScroll
4 | import zone.com.zrefreshlayout.ZRefreshLayout
5 |
6 | class ScrollDoNothing(mZRefreshLayout: ZRefreshLayout) : IScroll(mZRefreshLayout) {
7 | var scrollFy: Int = 0
8 | override fun scrollTo(fy: Int, isTriggerHeaderOnPullingDown: Boolean) {
9 | scrollFy = fy
10 | }
11 |
12 | override fun getScrollY(): Int = scrollFy
13 | }
14 |
15 |
--------------------------------------------------------------------------------
/zrefreshlayout/src/main/java/zone/com/zrefreshlayout/scroll/ScrollPin.kt:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayout.scroll
2 |
3 | import zone.com.zrefreshlayout.AUtils
4 | import zone.com.zrefreshlayout.IScroll
5 | import zone.com.zrefreshlayout.ZRefreshLayout
6 |
7 | class ScrollPin(mZRefreshLayout: ZRefreshLayout) : IScroll(mZRefreshLayout) {
8 |
9 | override fun scrollTo(fy: Int, isTriggerHeaderOnPullingDown: Boolean) {
10 | if (mZRefreshLayout.iHeaderView != null && isTriggerHeaderOnPullingDown) {
11 | val refreshAbleHeight = AUtils.getRefreshAbleHeight(mZRefreshLayout)
12 | mZRefreshLayout.iHeaderView.onPullingDown(1f * Math.abs(fy) / refreshAbleHeight, refreshAbleHeight.toFloat())
13 | }
14 | mZRefreshLayout.iHeaderView.view.translationY = fy.toFloat()
15 | }
16 |
17 | override fun getScrollY(): Int {
18 | return mZRefreshLayout.iHeaderView.view.translationY.toInt()
19 | }
20 | }
21 |
22 |
--------------------------------------------------------------------------------
/zrefreshlayout/src/main/java/zone/com/zrefreshlayout/scroll/ScrollPinNot.kt:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayout.scroll
2 |
3 | import zone.com.zrefreshlayout.AUtils
4 | import zone.com.zrefreshlayout.IScroll
5 | import zone.com.zrefreshlayout.ZRefreshLayout
6 |
7 | class ScrollPinNot(mZRefreshLayout: ZRefreshLayout) : IScroll(mZRefreshLayout) {
8 |
9 | override fun scrollTo(fy: Int, isTriggerHeaderOnPullingDown: Boolean) {
10 | if (mZRefreshLayout.iHeaderView != null && isTriggerHeaderOnPullingDown) {
11 | val refreshAbleHeight = AUtils.getRefreshAbleHeight(mZRefreshLayout)
12 | mZRefreshLayout.iHeaderView.onPullingDown(1f * Math.abs(fy) / refreshAbleHeight, refreshAbleHeight.toFloat())
13 | }
14 | mZRefreshLayout.scrollTo(0, -fy)
15 | }
16 |
17 | override fun getScrollY(): Int {
18 | return -mZRefreshLayout.scrollY
19 | }
20 | }
--------------------------------------------------------------------------------
/zrefreshlayout/src/main/java/zone/com/zrefreshlayout/scroll/listener/ScrollScale.kt:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayout.scroll.listener
2 |
3 | import androidx.core.view.ViewCompat
4 | import zone.com.zrefreshlayout.AUtils
5 | import zone.com.zrefreshlayout.IScroll
6 | import zone.com.zrefreshlayout.ZRefreshLayout
7 |
8 | //zone todo 设计成 addScroll的模式;
9 |
10 | class ScrollScale(mZRefreshLayout: ZRefreshLayout) : IScroll(mZRefreshLayout) {
11 |
12 | override fun scrollTo(fy: Int, isTriggerHeaderOnPullingDown: Boolean) {
13 | val contentHeight = AUtils.getContentHeight(mZRefreshLayout)
14 | val contentView = AUtils.getContentView(mZRefreshLayout)
15 | if (fy >= 0) {
16 | ViewCompat.setPivotY(contentView, 0f)
17 | ViewCompat.setScaleY(contentView, (contentHeight + fy) * 1f / contentHeight)
18 | } else {
19 | ViewCompat.setPivotY(contentView, contentHeight.toFloat())
20 | ViewCompat.setScaleY(contentView, (contentHeight - fy) * 1f / contentHeight)
21 | }
22 | }
23 | }
--------------------------------------------------------------------------------
/zrefreshlayout/src/main/java/zone/com/zrefreshlayout/scroll/listener/ScrollScroll.kt:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayout.scroll.listener
2 |
3 | import androidx.core.view.ViewCompat
4 | import zone.com.zrefreshlayout.AUtils
5 | import zone.com.zrefreshlayout.IScroll
6 | import zone.com.zrefreshlayout.ZRefreshLayout
7 |
8 | //zone todo 设计成 addScroll的模式;
9 |
10 | class ScrollScroll(mZRefreshLayout: ZRefreshLayout) : IScroll(mZRefreshLayout) {
11 |
12 | override fun scrollTo(fy: Int, isTriggerHeaderOnPullingDown: Boolean) {
13 | mZRefreshLayout.scrollTo(0, -fy)
14 | }
15 | }
--------------------------------------------------------------------------------
/zrefreshlayout/src/main/java/zone/com/zrefreshlayout/utils/DensityUtils.java:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayout.utils;
2 |
3 | import android.content.Context;
4 | import android.util.TypedValue;
5 |
6 | /**
7 | * 常用单位转换的辅助类
8 | *
1dp 在个个分辨率的换算比例
9 | *
ldpi:mdpi:hdpi:xdpi:xxdpi=3:4:6:8:12
10 | * @author zhy
11 | *
12 | */
13 | public class DensityUtils
14 | {
15 | private DensityUtils()
16 | {
17 | /* cannot be instantiated */
18 | throw new UnsupportedOperationException("cannot be instantiated");
19 | }
20 |
21 | /**
22 | * dp转px
23 | *
24 | * @param context
25 | * @param dpVal
26 | * @return
27 | */
28 | public static int dp2px(Context context, float dpVal)
29 | {
30 | return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
31 | dpVal, context.getResources().getDisplayMetrics());
32 | }
33 |
34 | /**
35 | * sp转px
36 | *
37 | * @param context
38 | * @param spVal
39 | * @return
40 | */
41 | public static int sp2px(Context context, float spVal)
42 | {
43 | return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
44 | spVal, context.getResources().getDisplayMetrics());
45 | }
46 |
47 | /**
48 | * px转dp
49 | *
50 | * @param context
51 | * @param pxVal
52 | * @return
53 | */
54 | public static float px2dp(Context context, float pxVal)
55 | {
56 | final float scale = context.getResources().getDisplayMetrics().density;
57 | return (pxVal / scale);
58 | }
59 |
60 | /**
61 | * px转sp
62 | *
63 | * @param context
64 | * @param pxVal
65 | * @return
66 | */
67 | public static float px2sp(Context context, float pxVal)
68 | {
69 | return (pxVal / context.getResources().getDisplayMetrics().scaledDensity);
70 | }
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/zrefreshlayout/src/main/java/zone/com/zrefreshlayout/utils/LogUtils.java:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayout.utils;
2 |
3 | import android.util.Log;
4 |
5 | /**
6 | * Created by fuzhipeng on 2017/1/16.
7 | */
8 |
9 | public class LogUtils {
10 |
11 | public static final String Z_REFRESH_LAYOUT = "ZRefreshLayout";
12 | public static boolean isDebug = true;
13 |
14 | public static void log(String str) {
15 | if (isDebug)
16 | Log.i(Z_REFRESH_LAYOUT, str);
17 | }
18 | public static void logE(String str) {
19 | if (isDebug)
20 | Log.e(Z_REFRESH_LAYOUT, str);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/zrefreshlayout/src/main/java/zone/com/zrefreshlayout/utils/RecyclerViewUtils.java:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayout.utils;
2 |
3 | import androidx.recyclerview.widget.RecyclerView;
4 | import android.view.View;
5 |
6 | /**
7 | * [2017] by Zone
8 | */
9 |
10 | public class RecyclerViewUtils {
11 | /**
12 | * 判断最后一个条目是否完全可见
13 | *
14 | * @param recyclerView
15 | * @return
16 | */
17 | public static boolean isLastItemVisible(RecyclerView recyclerView) {
18 | final RecyclerView.Adapter> adapter = recyclerView.getAdapter();
19 | // 如果未设置Adapter或者Adapter没有数据可以上拉刷新
20 | if (null == adapter || adapter.getItemCount() == 0) {
21 | return true;
22 | }
23 | // 最后一个条目View完全展示,可以刷新
24 | int lastVisiblePosition = getLastVisiblePosition(recyclerView);
25 | if (lastVisiblePosition >= recyclerView.getAdapter().getItemCount() - 1) {
26 | return recyclerView.getChildAt(recyclerView.getChildCount() - 1).getBottom()
27 | <= recyclerView.getBottom();
28 | }
29 | return false;
30 | }
31 | /**
32 | * 获取最后一个可见子View的位置下标
33 | *
34 | * @param recyclerView
35 | * @return
36 | */
37 | public static int getLastVisiblePosition(RecyclerView recyclerView) {
38 | View lastVisibleChild = recyclerView.getChildAt(recyclerView.getChildCount() - 1);
39 | return lastVisibleChild != null ? recyclerView.getChildAdapterPosition(lastVisibleChild) : -1;
40 | }
41 |
42 | /**
43 | * 判断第一个条目是否完全可见
44 | *
45 | * @param recyclerView
46 | * @return
47 | */
48 | public static boolean isFirstItemVisible(RecyclerView recyclerView) {
49 | final RecyclerView.Adapter> adapter = recyclerView.getAdapter();
50 | // 如果未设置Adapter或者Adapter没有数据可以下拉刷新
51 | if (null == adapter || adapter.getItemCount() == 0) {
52 | return true;
53 | }
54 | // 第一个条目完全展示,可以刷新
55 | if (getFirstVisiblePosition(recyclerView) == 0) {
56 | return recyclerView.getChildAt(0).getTop() >= recyclerView.getTop();
57 | }
58 | return false;
59 | }
60 |
61 | /**
62 | * 获取第一个可见子View的位置下标
63 | *
64 | * @param recyclerView
65 | * @return
66 | */
67 | public static int getFirstVisiblePosition(RecyclerView recyclerView) {
68 | View firstVisibleChild = recyclerView.getChildAt(0);
69 | return firstVisibleChild != null ?
70 | recyclerView.getChildAdapterPosition(firstVisibleChild) : -1;
71 | }
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/zrefreshlayout/src/main/java/zone/com/zrefreshlayout/utils/ScreenUtils.java:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayout.utils;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.util.DisplayMetrics;
6 | import android.util.Log;
7 |
8 | public class ScreenUtils {
9 |
10 |
11 | public static int[] getScreenPix(Activity context) {
12 | DisplayMetrics dm = new DisplayMetrics();
13 | context.getWindowManager().getDefaultDisplay().getMetrics(dm);
14 | int[] screen = new int[2];
15 | screen[0] = dm.widthPixels;
16 | screen[1] = dm.heightPixels;
17 | return screen;
18 | }
19 |
20 | public static int[] getScreenPixByResources(Context context) {
21 | DisplayMetrics dm2 = context.getResources().getDisplayMetrics();
22 | int[] screen = new int[2];
23 | screen[0] = dm2.widthPixels;
24 | screen[1] = dm2.heightPixels;
25 | return screen;
26 | }
27 |
28 | /**
29 | * 打印 显示信息
30 | */
31 | public static DisplayMetrics printDisplayInfo(Context context) {
32 | DisplayMetrics dm = context.getResources().getDisplayMetrics();
33 | StringBuilder sb = new StringBuilder();
34 | sb.append("_______ 显示信息: ");
35 | sb.append("\ndensity :").append(dm.density);
36 | sb.append("\ndensityDpi :").append(dm.densityDpi);
37 | sb.append("\nheightPixels :").append(dm.heightPixels);
38 | sb.append("\nwidthPixels :").append(dm.widthPixels);
39 | sb.append("\nscaledDensity :").append(dm.scaledDensity);
40 | sb.append("\nxdpi :").append(dm.xdpi);
41 | sb.append("\nydpi :").append(dm.ydpi);
42 | Log.i("ScreenUtils", sb.toString());
43 | return dm;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/zrefreshlayout/src/main/java/zone/com/zrefreshlayout/utils/SimpleAnimatorListener.java:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayout.utils;
2 |
3 | import android.animation.Animator;
4 |
5 | /**
6 | * [2017] by Zone
7 | */
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 |
--------------------------------------------------------------------------------
/zrefreshlayout/src/main/java/zone/com/zrefreshlayout/v4/CircleImageView.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package zone.com.zrefreshlayout.v4;
18 |
19 | import android.content.Context;
20 | import android.graphics.Canvas;
21 | import android.graphics.Color;
22 | import android.graphics.Paint;
23 | import android.graphics.RadialGradient;
24 | import android.graphics.Shader;
25 | import android.graphics.drawable.ShapeDrawable;
26 | import android.graphics.drawable.shapes.OvalShape;
27 | import androidx.core.view.ViewCompat;
28 |
29 | import android.view.View;
30 | import android.view.animation.Animation;
31 | import android.widget.ImageView;
32 |
33 | /**
34 | * Private class created to work around issues with AnimationListeners being
35 | * called before the animation is actually loadMoreAnimationComplete and support shadows on older
36 | * platforms.
37 | *
38 | */
39 | public class CircleImageView extends ImageView {
40 |
41 | private static final int KEY_SHADOW_COLOR = 0x1E000000;
42 | private static final int FILL_SHADOW_COLOR = 0x3D000000;
43 | // PX
44 | private static final float X_OFFSET = 0f;
45 | private static final float Y_OFFSET = 1.75f;
46 | private static final float SHADOW_RADIUS = 3.5f;
47 | private static final int SHADOW_ELEVATION = 4;
48 |
49 | private Animation.AnimationListener mListener;
50 | int mShadowRadius;
51 |
52 | public CircleImageView(Context context, int color) {
53 | super(context);
54 | final float density = getContext().getResources().getDisplayMetrics().density;
55 | final int shadowYOffset = (int) (density * Y_OFFSET);
56 | final int shadowXOffset = (int) (density * X_OFFSET);
57 |
58 | mShadowRadius = (int) (density * SHADOW_RADIUS);
59 |
60 | ShapeDrawable circle;
61 | if (elevationSupported()) {
62 | circle = new ShapeDrawable(new OvalShape());
63 | ViewCompat.setElevation(this, SHADOW_ELEVATION * density);
64 | } else {
65 | OvalShape oval = new OvalShadow(mShadowRadius);
66 | circle = new ShapeDrawable(oval);
67 | setLayerType(View.LAYER_TYPE_SOFTWARE, circle.getPaint());
68 | circle.getPaint().setShadowLayer(mShadowRadius, shadowXOffset, shadowYOffset,
69 | KEY_SHADOW_COLOR);
70 | final int padding = mShadowRadius;
71 | // set padding so the inner image sits correctly within the shadow.
72 | setPadding(padding, padding, padding, padding);
73 | }
74 | circle.getPaint().setColor(color);
75 | setBackgroundDrawable(circle);
76 | }
77 |
78 | private boolean elevationSupported() {
79 | return android.os.Build.VERSION.SDK_INT >= 21;
80 | }
81 |
82 | @Override
83 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
84 | super.onMeasure(widthMeasureSpec, heightMeasureSpec);
85 | if (!elevationSupported()) {
86 | setMeasuredDimension(getMeasuredWidth() + mShadowRadius * 2, getMeasuredHeight()
87 | + mShadowRadius * 2);
88 | }
89 | }
90 |
91 | public void setAnimationListener(Animation.AnimationListener listener) {
92 | mListener = listener;
93 | }
94 |
95 | @Override
96 | public void onAnimationStart() {
97 | super.onAnimationStart();
98 | if (mListener != null) {
99 | mListener.onAnimationStart(getAnimation());
100 | }
101 | }
102 |
103 | @Override
104 | public void onAnimationEnd() {
105 | super.onAnimationEnd();
106 | if (mListener != null) {
107 | mListener.onAnimationEnd(getAnimation());
108 | }
109 | }
110 |
111 | /**
112 | * Update the background color of the circle image view.
113 | *
114 | * @param colorRes Id of a color resource.
115 | */
116 | public void setBackgroundColorRes(int colorRes) {
117 | setBackgroundColor(getContext().getResources().getColor(colorRes));
118 | }
119 |
120 | @Override
121 | public void setBackgroundColor(int color) {
122 | if (getBackground() instanceof ShapeDrawable) {
123 | ((ShapeDrawable) getBackground()).getPaint().setColor(color);
124 | }
125 | }
126 |
127 | private class OvalShadow extends OvalShape {
128 | private RadialGradient mRadialGradient;
129 | private Paint mShadowPaint;
130 |
131 | OvalShadow(int shadowRadius) {
132 | super();
133 | mShadowPaint = new Paint();
134 | mShadowRadius = shadowRadius;
135 | updateRadialGradient((int) rect().width());
136 | }
137 |
138 | @Override
139 | protected void onResize(float width, float height) {
140 | super.onResize(width, height);
141 | updateRadialGradient((int) width);
142 | }
143 |
144 | @Override
145 | public void draw(Canvas canvas, Paint paint) {
146 | final int viewWidth = CircleImageView.this.getWidth();
147 | final int viewHeight = CircleImageView.this.getHeight();
148 | canvas.drawCircle(viewWidth / 2, viewHeight / 2, viewWidth / 2, mShadowPaint);
149 | canvas.drawCircle(viewWidth / 2, viewHeight / 2, viewWidth / 2 - mShadowRadius, paint);
150 | }
151 |
152 | private void updateRadialGradient(int diameter) {
153 | mRadialGradient = new RadialGradient(diameter / 2, diameter / 2,
154 | mShadowRadius, new int[] { FILL_SHADOW_COLOR, Color.TRANSPARENT },
155 | null, Shader.TileMode.CLAMP);
156 | mShadowPaint.setShader(mRadialGradient);
157 | }
158 | }
159 | }
160 |
--------------------------------------------------------------------------------
/zrefreshlayout/src/main/java/zone/com/zrefreshlayout/v4/MeterialCircle.java:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayout.v4;
2 |
3 | import android.graphics.Color;
4 | import androidx.core.view.ViewCompat;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 | import android.view.animation.Animation;
8 | import android.view.animation.Transformation;
9 | import android.widget.FrameLayout;
10 | import android.widget.LinearLayout;
11 |
12 | import static zone.com.zrefreshlayout.utils.LogUtils.log;
13 |
14 | /**
15 | * Created by fuzhipeng on 2017/1/13.
16 | */
17 |
18 | public class MeterialCircle {
19 | // Default background for the progress spinner
20 | private static final int CIRCLE_BG_LIGHT = 0xFFFAFAFA;
21 | private CircleImageView mCircleView;
22 | private MaterialProgressDrawable mProgress;
23 | // private static final int SCALE_DOWN_DURATION = 150;
24 | private static final int SCALE_DOWN_DURATION = 255;
25 | private static final int MAX_ALPHA = 255;
26 |
27 | int[] colors_red_green_yellow = new int[]{
28 | Color.parseColor("#ffF44336"),
29 | Color.parseColor("#ff4CAF50"),
30 | Color.parseColor("#ffFFEB3B")
31 | };
32 | public MeterialCircle(ViewGroup vp, int width2height) {
33 | //注意inflate那种模式 第一层需要空出去 不然会wrapcontent
34 | mCircleView = new CircleImageView(vp.getContext(), CIRCLE_BG_LIGHT);
35 | mCircleView.setLayoutParams(new FrameLayout.LayoutParams(width2height, width2height));
36 | mProgress = new MaterialProgressDrawable(vp.getContext(), vp);
37 | mProgress.setBackgroundColor(CIRCLE_BG_LIGHT);
38 | mProgress.setColorSchemeColors(colors_red_green_yellow);
39 | mCircleView.setImageDrawable(mProgress);
40 | // vp.addView(mCircleView);
41 | // mCircleView.setVisibility(View.GONE);
42 | }
43 |
44 | public CircleImageView getView(){
45 | return mCircleView;
46 | }
47 | public void setRadius(int width2height) {
48 | mCircleView.setLayoutParams(new LinearLayout.LayoutParams(width2height, width2height));
49 | }
50 |
51 | public void setColorSchemeColors(int... colors) {
52 | mProgress.setColorSchemeColors(colors);
53 | }
54 |
55 |
56 | /**
57 | * Pre API 11, this does an alpha animation.
58 | *
59 | * @param progress
60 | */
61 | void setAnimationProgress(float progress) {
62 | if (android.os.Build.VERSION.SDK_INT < 11) {
63 | setColorViewAlpha((int) (progress * MAX_ALPHA));
64 | } else {
65 | ViewCompat.setScaleX(mCircleView, progress);
66 | ViewCompat.setScaleY(mCircleView, progress);
67 | }
68 | }
69 |
70 | private void setColorViewAlpha(int targetAlpha) {
71 | mCircleView.getBackground().setAlpha(targetAlpha);
72 | mProgress.setAlpha(targetAlpha);
73 | }
74 |
75 |
76 | public void pullProgress(float fraction) {
77 | float percent = Math.min(1f, fraction);
78 | mProgress.setAlpha((int) (255 * percent));
79 | mProgress.showArrow(true);
80 |
81 | float strokeStart = ((percent) * .8f);
82 | mProgress.setStartEndTrim(0f, Math.min(0.8f, strokeStart));
83 | mProgress.setArrowScale(Math.min(1f, percent));
84 |
85 | // magic
86 | float rotation = (-0.25f + .4f * percent + percent * 2) * .5f;
87 | mProgress.setProgressRotation(rotation);
88 | }
89 |
90 | boolean isStart;
91 | public void start() {
92 | pullProgress(1);
93 | mProgress.showArrow(false);
94 | mProgress.setAlpha(MAX_ALPHA);
95 | isStart=true;
96 | mProgress.start();
97 |
98 | }
99 |
100 | public void reset() {
101 | circleStop();
102 | mCircleView.setVisibility(View.VISIBLE);
103 | setAnimationProgress(1);
104 | }
105 |
106 | private void circleStop() {
107 | if(isStart){
108 | mProgress.stop();
109 | isStart=false;
110 | }
111 | }
112 |
113 | public void startScaleDownAnimation(final ScaleDownCallback mScaleDownCallback) {
114 | Animation mScaleDownAnimation = new Animation() {
115 | @Override
116 | public void applyTransformation(float interpolatedTime, Transformation t) {
117 | setAnimationProgress(1 - interpolatedTime);
118 | log("interpolatedTime"+(1 - interpolatedTime));
119 | }
120 | };
121 | mScaleDownAnimation.setDuration(SCALE_DOWN_DURATION);
122 | mCircleView.setAnimationListener(new Animation.AnimationListener() {
123 | @Override
124 | public void onAnimationStart(Animation animation) {
125 |
126 | }
127 |
128 | @Override
129 | public void onAnimationEnd(Animation animation) {
130 | log("onAnimationEnd------->");
131 | mCircleView.clearAnimation();
132 | circleStop();
133 | if (mScaleDownCallback != null)
134 | mScaleDownCallback.over();
135 | }
136 |
137 | @Override
138 | public void onAnimationRepeat(Animation animation) {
139 |
140 | }
141 | });
142 | mCircleView.clearAnimation();
143 | mCircleView.startAnimation(mScaleDownAnimation);
144 |
145 | }
146 |
147 | public interface ScaleDownCallback {
148 | void over();
149 | }
150 | }
151 |
--------------------------------------------------------------------------------
/zrefreshlayout/src/main/res/drawable-xxhdpi/ic_arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luhaoaimama1/ZRefreshLayout/1226a2d020b718687865b369810d069328e547cb/zrefreshlayout/src/main/res/drawable-xxhdpi/ic_arrow.png
--------------------------------------------------------------------------------
/zrefreshlayout/src/main/res/drawable-xxhdpi/refresh_loading01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luhaoaimama1/ZRefreshLayout/1226a2d020b718687865b369810d069328e547cb/zrefreshlayout/src/main/res/drawable-xxhdpi/refresh_loading01.png
--------------------------------------------------------------------------------
/zrefreshlayout/src/main/res/layout/footer.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
15 |
16 |
--------------------------------------------------------------------------------
/zrefreshlayout/src/main/res/layout/header.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
14 |
--------------------------------------------------------------------------------
/zrefreshlayout/src/main/res/layout/header_meterial.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
--------------------------------------------------------------------------------
/zrefreshlayout/src/main/res/layout/view_sinaheader.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
14 |
20 |
21 |
28 |
29 |
36 |
37 |
--------------------------------------------------------------------------------
/zrefreshlayout/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | zrefreshlayout
3 |
4 |
--------------------------------------------------------------------------------
/zrefreshlayout/src/test/java/zone/com/zrefreshlayoutdemo/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package zone.com.zrefreshlayoutdemo;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------