diff --git a/README.md b/README.md
index b4dfe5d..02c98ad 100644
--- a/README.md
+++ b/README.md
@@ -1,38 +1,113 @@
# XRefreshView
-###Usage
+### Usage
----
#### Gradle
```groovy
dependencies {
- compile 'com.huxq17.xrefreshview:xrefreshview:3.0.0'
+ compile 'com.huxq17.xrefreshview:xrefreshview:3.6.9'
//依赖下面的库
- compile 'com.android.support:recyclerview-v7:23.0.1'
- compile 'com.android.support:support-v4:23.0.1'
+ implementation 'androidx.recyclerview:recyclerview:1.1.0'
}
```
-##最新的使用说明请移步[我的博客](http://blog.csdn.net/footballclub/article/details/46982115 "description")
-##效果图
-###带Banner的Recyclerview
-![带Banner的Recyclerview](http://img.my.csdn.net/uploads/201602/15/1455502311_5774.gif)
-###LinearLayout样式的Recyclerview
-![LinearLayout样式的Recyclerview](http://img.my.csdn.net/uploads/201602/03/1454495499_9614.gif)
-###GridLayout样式的Recyclerview
-![GridLayout样式的Recyclerview](http://img.my.csdn.net/uploads/201602/03/1454495517_6621.gif)
-###Staggered样式的Recyclerview
-![Staggered样式的Recyclerview](http://img.my.csdn.net/uploads/201602/03/1454495499_9854.gif)
-###GridView
-![自带的头部](http://img.my.csdn.net/uploads/201508/25/1440465457_8215.gif)
-###自定义View
-![自定义头部](http://img.my.csdn.net/uploads/201508/25/1440465306_9400.gif)
-
-还有listview,scrollview,webview等其他的view就不一一截图了。
+## 最新的使用说明请移步[我的博客](http://blog.csdn.net/footballclub/article/details/46982115 "description")
+
+## 效果图
+
+|松开加载更多的Recyclerview|带Banner的Recyclerview| LinearLayout样式的Recyclerview|
+|:-----|:-----|:-----|
+|
|
|
|
+
+|GridLayout样式的Recyclerview|Staggered样式的Recyclerview|
+|:-----|:-----|
+|
|
|
+
+|GridView|自定义View|笑脸刷新|
+|:-----|:-----|:-----|
+|
|
|
|
+
+|自定义刷新|仿京东刷新|自定义刷新|
+|:-----|:-----|:-----|
+|
|
|
|
+
+
+还有listview,scrollview,webview等其他的view就不一一截图了。**建议把此项目下载下来,然后跑到手机上看效果,例子都在app module里。**
+
+### 更新日志:
+
+ 2020-6-13:
+ 1.更新android平台到androidx
+
+
+ 2017-5-4:
+ 1.解决已无更多数据显示不出来的问题,fix issue[#78](https://github.com/huxq17/XRefreshView/issues/78)
+ 2.升级到3.6.9版本
+
+ 2017-5-3:
+ 1.解决xrefreshview不满屏的时候footerview正常状态下出现在屏幕上的问题,fix issue[#75](https://github.com/huxq17/XRefreshView/issues/75)
+ 2.升级到3.6.8版本
+
+ 2017-4-25:
+ 1.通过使用XWebView,解决在三星c5、小米5等机型在webview上加XRefreshView,会出现加载更多没有效果的现象,详见issue[#72](https://github.com/huxq17/XRefreshView/issues/72)
+ 2.升级到3.6.7版本
+
+ 2017-4-14:
+ 1.解决Recyclerview频繁上拉加载时会出现footerview位置异常的问题
+ 2.给setSilenceLoadMore方法添加boolean参数,可以启用和禁用静默加载模式
+ 3.升级到3.6.6版本
+
+ 2017-3-28:
+ 1.不再强制Recyclerview使用BaseRecyclerAdapter,当不使用BaseRecyclerAdapter时,RecyclerView会被当成普通view
+ 上拉加载等操作和普通view相同,空布局等功能的使用方式也和普通view相同
+ 2.解决ListView的子项目不足一屏时,上拉时再下拉会出现布局突然缩回的问题
+ 3.升级到3.6.5版本
+
+ 2017-3-27:
+ 1.解决事先setPullRefreshEnable(false),再setPullRefreshEnable(true)和startRefresh()时,headerview无法显示的问题
+ 2.升级到3.6.3版本
+
+ 2017-2-17:
+ 1.添加下拉刷新时的回调onRefresh(boolean isPullDown),其中isPullDown用来判断此次下拉刷新是不是由下拉手势触发的,true则代表是,
+ 反之则是自动刷新或者是调用XRefreshView#startRefresh()}触发的刷新
+ 2.升级到3.6.2版本
+
+ 2017-2-16:
+ 1.解决issue[#58](https://github.com/huxq17/XRefreshView/issues/58)
+
+ 2017-1-13:
+ 1.解决Recyclerview使用StaggeredGridLayoutManager时,添加的headerview不能使用全部宽度的问题(headview layout won't use all span area)
+
+ 2017-1-6:
+ 1.解决issue[#49](https://github.com/huxq17/XRefreshView/issues/49)
+
+ 2017-1-4:
+ 1.解决AbsListview数据不满一屏的时候,会重复加载更多的问题
+
+ 2016-12-15:
+ 1.优化非RecyclerView上拉加载回弹的效果,同时支持AbsListView(ListView、GridView)加载更多数据完成之后露出新加载的数据
+
+ 2016-9-28:
+ 1.添加xscrollview的滑动监听
+
+ 2016-9-6:
+ 1.解决issue[#36](https://github.com/huxq17/XRefreshView/issues/36)
+
+ 2016-8-19:
+ 1.添加没有数据时显示空布局的支持
+ 2.解决6.0以下的手机,在调用startRefresh()方法后,刷新时headerview有时会不显示的问题
+ 3.其他一些优化
+
+ 2016-8-8:
+ 1.添加下拉刷新,数据接收失败的ui处理
+ 2.解决下拉刷新,在刷新状态下把headerview完全隐藏掉,在刷新结束以后下拉和上拉都不可用的问题
+
### 关于我
-QQ:1491359569 邮箱:huxq17@163.com
+ 邮箱:huxq17@163.com fanyafeng@live.cn
+ ps:有问题联系我的话请不要问我在不在,直接说问题,谢谢。
### License
diff --git a/app/build.gradle b/app/build.gradle
index 4153c71..436ee6c 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -1,13 +1,14 @@
apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
android {
- compileSdkVersion 23
- buildToolsVersion "23.0.1"
+ compileSdkVersion 29
+ buildToolsVersion "29.0.3"
defaultConfig {
applicationId "com.andview.example"
- minSdkVersion 11
- targetSdkVersion 23
+ minSdkVersion 19
+ targetSdkVersion 29
versionCode 1
versionName "1.0"
}
@@ -21,13 +22,17 @@ android {
abortOnError false
}
}
-
dependencies {
- compile fileTree(include: ['*.jar'], dir: 'libs')
- compile project(':library')
-// compile 'com.huxq17.xrefreshview:xrefreshview:3.2.0'
+ implementation fileTree(include: ['*.jar'], dir: 'libs')
+ implementation project(':library')
+// compile 'com.huxq17.xrefreshview:xrefreshview:3.6.9'
//依赖下面的库
- compile 'com.android.support:recyclerview-v7:23.0.1'
- compile 'com.android.support:support-v4:23.0.1'
- compile 'com.android.support:cardview-v7:23.1.1'
+ implementation 'androidx.recyclerview:recyclerview:1.1.0'
+ implementation 'androidx.cardview:cardview:1.0.0'
+ implementation 'androidx.appcompat:appcompat:1.1.0'
+ implementation "androidx.core:core-ktx:+"
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+}
+repositories {
+ mavenCentral()
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 074b9ce..05da284 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -3,6 +3,7 @@
package="com.andview.example">
+
-
-
+
+
-
-
-
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
-
+
\ No newline at end of file
diff --git a/app/src/main/java/com/andview/example/IndexPageAdapter.java b/app/src/main/java/com/andview/example/IndexPageAdapter.java
index ea5dbcd..7b91ac6 100644
--- a/app/src/main/java/com/andview/example/IndexPageAdapter.java
+++ b/app/src/main/java/com/andview/example/IndexPageAdapter.java
@@ -2,14 +2,14 @@
import android.content.Context;
import android.os.Parcelable;
-import android.support.v4.view.PagerAdapter;
-import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
+import androidx.viewpager.widget.PagerAdapter;
+
public class IndexPageAdapter extends PagerAdapter {
private int[] images;
@@ -24,7 +24,7 @@ public IndexPageAdapter(Context context, int[] images) {
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
- ((ViewPager) container).removeView((View) object);
+ container.removeView((View) object);
}
@Override
@@ -45,7 +45,7 @@ public Object instantiateItem(ViewGroup view, int position) {
final int index = position % images.length;
imageView.setBackgroundResource(images[index]);
- ((ViewPager) view).addView(imageLayout, 0);
+ view.addView(imageLayout, 0);
return imageLayout;
}
diff --git a/app/src/main/java/com/andview/example/ScrollAdapter.java b/app/src/main/java/com/andview/example/ScrollAdapter.java
new file mode 100644
index 0000000..7649dce
--- /dev/null
+++ b/app/src/main/java/com/andview/example/ScrollAdapter.java
@@ -0,0 +1,114 @@
+package com.andview.example;
+
+import android.content.Context;
+import android.os.Parcelable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+import android.widget.ScrollView;
+import android.widget.TextView;
+
+import androidx.viewpager.widget.PagerAdapter;
+
+import com.andview.example.ui.raindrop.CustomerFooter;
+import com.andview.refreshview.XRefreshView;
+import com.andview.refreshview.XScrollView;
+
+public class ScrollAdapter extends PagerAdapter {
+
+ private int[] images;
+ private Context mContext;
+ private LayoutInflater mInflater;
+
+ public ScrollAdapter(Context context) {
+ this.mContext = context;
+ mInflater = LayoutInflater.from(mContext);
+ }
+
+ @Override
+ public void destroyItem(ViewGroup container, int position, Object object) {
+ container.removeView((View) object);
+ }
+
+ @Override
+ public void finishUpdate(View container) {
+ }
+
+ @Override
+ public int getCount() {
+ return Integer.MAX_VALUE;
+ }
+
+ @Override
+ public Object instantiateItem(ViewGroup view, int position) {
+ final View imageLayout = mInflater.inflate(R.layout.adapter_scrollview, view, false);
+ final XRefreshView outView = (XRefreshView) imageLayout.findViewById(R.id.custom_view);
+ final XScrollView scrollView = (XScrollView) imageLayout.findViewById(R.id.xscrollview);
+ scrollView.setOnScrollListener(new XScrollView.OnScrollListener() {
+ @Override
+ public void onScrollStateChanged(ScrollView view, int scrollState, boolean arriveBottom) {
+ }
+
+ @Override
+ public void onScroll(int l, int t, int oldl, int oldt) {
+ }
+ });
+ outView.setAutoRefresh(false);
+ outView.setPullLoadEnable(true);
+ outView.setPinnedTime(1000);
+ outView.setAutoLoadMore(false);
+// outView.setSilenceLoadMore();
+ outView.setXRefreshViewListener(new XRefreshView.SimpleXRefreshListener() {
+ @Override
+ public void onLoadMore(boolean isSilence) {
+ imageLayout.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ outView.stopLoadMore();
+ }
+ }, 2000);
+ }
+
+ @Override
+ public void onRefresh(boolean isPullDown) {
+ imageLayout.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ outView.stopRefresh();
+ }
+ }, 2000);
+ }
+ });
+ outView.setCustomFooterView(new CustomerFooter(mContext));
+ LinearLayout ll = (LinearLayout) imageLayout.findViewById(R.id.ll);
+ for (int i = 0; i < 50; i++) {
+ TextView tv = new TextView(mContext);
+ tv.setTextIsSelectable(true);
+ tv.setText("数据" + i);
+ ll.addView(tv);
+ }
+ view.addView(imageLayout, 0);
+
+ return imageLayout;
+ }
+
+ @Override
+ public boolean isViewFromObject(View view, Object object) {
+ return view.equals(object);
+ }
+
+ @Override
+ public void restoreState(Parcelable state, ClassLoader loader) {
+ }
+
+ @Override
+ public Parcelable saveState() {
+ return null;
+ }
+
+ @Override
+ public void startUpdate(View container) {
+ }
+
+}
diff --git a/app/src/main/java/com/andview/example/activity/CarCrmActivity.java b/app/src/main/java/com/andview/example/activity/CarCrmActivity.java
new file mode 100644
index 0000000..cefb61a
--- /dev/null
+++ b/app/src/main/java/com/andview/example/activity/CarCrmActivity.java
@@ -0,0 +1,46 @@
+package com.andview.example.activity;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.Handler;
+
+import com.andview.example.R;
+import com.andview.example.view.XRefreshViewCarHeader;
+import com.andview.refreshview.XRefreshView;
+
+public class CarCrmActivity extends Activity {
+
+ private XRefreshView carCrmXRefreshView;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_car_crm);
+ initView();
+ initData();
+ }
+
+ private void initView() {
+ carCrmXRefreshView = (XRefreshView) findViewById(R.id.carCrmXRefreshView);
+ carCrmXRefreshView.setCustomHeaderView(new XRefreshViewCarHeader(this));
+ carCrmXRefreshView.setMoveForHorizontal(true);
+ }
+
+ private void initData() {
+ carCrmXRefreshView.setAutoRefresh(false);
+ carCrmXRefreshView.setPullRefreshEnable(true);
+ carCrmXRefreshView.setMoveForHorizontal(true);
+ carCrmXRefreshView.setXRefreshViewListener(new XRefreshView.SimpleXRefreshListener() {
+ @Override
+ public void onRefresh(boolean isPullDown) {
+ super.onRefresh(isPullDown);
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ carCrmXRefreshView.stopRefresh();
+ }
+ }, 2000);
+ }
+ });
+ }
+}
diff --git a/app/src/main/java/com/andview/example/activity/CustomViewActivity.java b/app/src/main/java/com/andview/example/activity/CustomViewActivity.java
index 47a0cc0..a3d94ec 100644
--- a/app/src/main/java/com/andview/example/activity/CustomViewActivity.java
+++ b/app/src/main/java/com/andview/example/activity/CustomViewActivity.java
@@ -3,6 +3,7 @@
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
+import android.view.View;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
@@ -11,7 +12,7 @@
import com.andview.example.StickylistAdapter;
import com.andview.example.stickyListHeaders.StickyListHeadersListView;
import com.andview.example.ui.CustomHeader;
-import com.andview.example.ui.raindrop.CustomerFooter;
+import com.andview.example.ui.smileyloadingview.SmileyHeaderView;
import com.andview.refreshview.XRefreshView;
import com.andview.refreshview.listener.OnBottomLoadMoreTime;
import com.andview.refreshview.listener.OnTopRefreshTime;
@@ -20,96 +21,106 @@
import java.util.List;
public class CustomViewActivity extends Activity {
- private StickyListHeadersListView stickyLv;
- private List list = new ArrayList();
- private XRefreshView refreshView;
- private int mTotalItemCount;
- private StickylistAdapter adapter;
-
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_customview);
- initData();
- stickyLv = (StickyListHeadersListView) findViewById(R.id.sticky_list);
- adapter = new StickylistAdapter(getApplicationContext(), list);
- stickyLv.setAdapter(adapter);
- refreshView = (XRefreshView) findViewById(R.id.custom_view);
- refreshView.setPullLoadEnable(true);
- refreshView.setAutoRefresh(true);
-// refreshView.setPinnedTime(0);
- refreshView.setCustomHeaderView(new CustomHeader(this));
- refreshView.setCustomFooterView(new CustomerFooter(this));
- refreshView.setOnTopRefreshTime(new OnTopRefreshTime() {
-
- @Override
- public boolean isTop() {
- return stickyLv.getFirstVisiblePosition() == 0;
- }
- });
- refreshView.setOnBottomLoadMoreTime(new OnBottomLoadMoreTime() {
-
- @Override
- public boolean isBottom() {
- return stickyLv.getLastVisiblePosition() == mTotalItemCount - 1;
- }
- });
- stickyLv.setOnScrollListener(new OnScrollListener() {
-
- @Override
- public void onScrollStateChanged(AbsListView view, int scrollState) {
-
- }
-
- @Override
- public void onScroll(AbsListView view, int firstVisibleItem,
- int visibleItemCount, int totalItemCount) {
- mTotalItemCount = totalItemCount;
- }
- });
- refreshView.setXRefreshViewListener(new XRefreshView.SimpleXRefreshListener() {
-
- @Override
- public void onRefresh() {
-
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- refreshView.stopRefresh();
- }
- }, 10000);
- }
-
- @Override
- public void onLoadMore(boolean isSlience) {
-
- new Handler().postDelayed(new Runnable() {
-
- @Override
- public void run() {
- refreshView.stopLoadMore();
- }
- }, 2000);
- }
- });
- }
-
- int section = 1;
- String YM = null;
- String content = null;
-
- private void initData() {
-
- for (int i = 0; i < 20; i++) {
- if (i % 5 == 0) {
- section++;
- YM = "第" + section + "个头";
- }
- content = "第" + i + "项数据";
- StickyListBean bean = new StickyListBean(section, YM, content);
- list.add(bean);
- }
-
- }
+ private StickyListHeadersListView stickyLv;
+ private List list = new ArrayList();
+ private XRefreshView refreshView;
+ private int mTotalItemCount;
+ private StickylistAdapter adapter;
+ private final int mPinnedTime = 1000;
+
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_customview);
+ initData();
+ stickyLv = (StickyListHeadersListView) findViewById(R.id.sticky_list);
+ adapter = new StickylistAdapter(getApplicationContext(), list);
+ stickyLv.setAdapter(adapter);
+ refreshView = (XRefreshView) findViewById(R.id.custom_view);
+ refreshView.setPullLoadEnable(true);
+ refreshView.setAutoRefresh(true);
+ refreshView.setPinnedTime(mPinnedTime);
+ refreshView.setCustomHeaderView(new SmileyHeaderView(this));
+ refreshView.setCustomHeaderView(new CustomHeader(CustomViewActivity.this,mPinnedTime));
+ refreshView.setOnTopRefreshTime(new OnTopRefreshTime() {
+
+ @Override
+ public boolean isTop() {
+ if (stickyLv.getFirstVisiblePosition() == 0) {
+ View firstVisibleChild = stickyLv.getListChildAt(0);
+ return firstVisibleChild.getTop() >= 0;
+ }
+ return false;
+ }
+ });
+ refreshView.setOnBottomLoadMoreTime(new OnBottomLoadMoreTime() {
+
+ @Override
+ public boolean isBottom() {
+ if (stickyLv.getLastVisiblePosition() == mTotalItemCount - 1) {
+ View lastChild = stickyLv.getListChildAt(stickyLv.getListChildCount() - 1);
+ return (lastChild.getBottom() + stickyLv.getPaddingBottom()) <= stickyLv.getMeasuredHeight();
+ }
+ //没有到达底部则返回false
+ return false;
+ }
+ });
+ stickyLv.setOnScrollListener(new OnScrollListener() {
+
+ @Override
+ public void onScrollStateChanged(AbsListView view, int scrollState) {
+
+ }
+
+ @Override
+ public void onScroll(AbsListView view, int firstVisibleItem,
+ int visibleItemCount, int totalItemCount) {
+ mTotalItemCount = totalItemCount;
+ }
+ });
+ refreshView.setXRefreshViewListener(new XRefreshView.SimpleXRefreshListener() {
+
+ @Override
+ public void onRefresh(boolean isPullDown) {
+
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ refreshView.stopRefresh();
+ }
+ }, 2000);
+ }
+
+ @Override
+ public void onLoadMore(boolean isSilence) {
+
+ new Handler().postDelayed(new Runnable() {
+
+ @Override
+ public void run() {
+ refreshView.stopLoadMore();
+ }
+ }, 2000);
+ }
+ });
+ }
+
+ int section = 0;
+ String YM = null;
+ String content = null;
+
+ private void initData() {
+
+ for (int i = 0; i < 20; i++) {
+ if (i % 5 == 0) {
+ section++;
+ YM = "第" + section + "个头";
+ }
+ content = "第" + i + "项数据";
+ StickyListBean bean = new StickyListBean(section, YM, content);
+ list.add(bean);
+ }
+
+ }
}
diff --git a/app/src/main/java/com/andview/example/activity/EmptyViewActivity.java b/app/src/main/java/com/andview/example/activity/EmptyViewActivity.java
new file mode 100644
index 0000000..a76191a
--- /dev/null
+++ b/app/src/main/java/com/andview/example/activity/EmptyViewActivity.java
@@ -0,0 +1,207 @@
+package com.andview.example.activity;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.andview.example.DensityUtil;
+import com.andview.example.R;
+import com.andview.example.recylerview.Person;
+import com.andview.example.recylerview.SimpleAdapter;
+import com.andview.refreshview.XRefreshView;
+import com.andview.refreshview.XRefreshViewFooter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class EmptyViewActivity extends Activity {
+ private RecyclerView recyclerView;
+ private SimpleAdapter recyclerviewAdapter;
+ private List personList = new ArrayList();
+ private XRefreshView xRefreshView1;
+ private LinearLayoutManager layoutManager;
+ private boolean isBottom = false;
+
+ private LinearLayout linearLayout;
+ private XRefreshView xRefreshView2;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_emptyview);
+ initRecyclerView();
+ initScrollView();
+ configXRfreshView(xRefreshView1, new XRefreshView.SimpleXRefreshListener() {
+
+ @Override
+ public void onRefresh(boolean isPullDown) {
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ xRefreshView1.stopRefresh();
+ }
+ }, 500);
+ }
+
+ @Override
+ public void onLoadMore(boolean isSilence) {
+ new Handler().postDelayed(new Runnable() {
+ public void run() {
+ for (int i = 0; i < 1; i++) {
+ recyclerviewAdapter.insert(new Person("More ", "21" + recyclerviewAdapter.getAdapterItemCount()),
+ recyclerviewAdapter.getAdapterItemCount());
+ }
+ // 刷新完成必须调用此方法停止加载
+ xRefreshView1.stopLoadMore();
+ }
+ }, 1000);
+ }
+ });
+ configXRfreshView(xRefreshView2, new XRefreshView.SimpleXRefreshListener() {
+
+ @Override
+ public void onRefresh() {
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ xRefreshView2.stopRefresh();
+ }
+ }, 500);
+ }
+
+ @Override
+ public void onLoadMore(boolean isSilence) {
+ new Handler().postDelayed(new Runnable() {
+ public void run() {
+ // 刷新完成必须调用此方法停止加载
+ xRefreshView2.stopLoadMore();
+ }
+ }, 1000);
+ }
+ });
+ setEmptyViewClickListener(xRefreshView1, new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ requestRecyclerViewData();
+ }
+ });
+ setEmptyViewClickListener(xRefreshView2, new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ //非Recyclerview得在有数据和没有数据的时候,手动调用enableEmptyView方法来显示和关闭emptyView。
+ xRefreshView2.enableEmptyView(false);
+ }
+ });
+ requestRecyclerViewData();
+ requestScrllViewData();
+ }
+
+ private void setEmptyViewClickListener(XRefreshView xRefreshView, View.OnClickListener listener) {
+ View emptyView = xRefreshView.getEmptyView();
+ if (emptyView != null) {
+ emptyView.setOnClickListener(listener);
+ }
+ }
+
+ private void initRecyclerView() {
+ xRefreshView1 = (XRefreshView) findViewById(R.id.xrefreshview);
+ recyclerView = (RecyclerView) findViewById(R.id.recycler_view_test_rv);
+ recyclerView.setHasFixedSize(true);
+
+ recyclerviewAdapter = new SimpleAdapter(personList, this);
+ layoutManager = new LinearLayoutManager(this);
+ recyclerView.setLayoutManager(layoutManager);
+ recyclerView.setAdapter(recyclerviewAdapter);
+ recyclerviewAdapter.setCustomLoadMoreView(new XRefreshViewFooter(this));
+ }
+
+ private void initScrollView() {
+ xRefreshView2 = (XRefreshView) findViewById(R.id.xrefreshview2);
+ linearLayout = (LinearLayout) findViewById(R.id.linearLayout);
+
+ }
+
+ private void configXRfreshView(XRefreshView xRefreshView, XRefreshView.SimpleXRefreshListener listener) {
+ xRefreshView.setPullLoadEnable(true);
+ //设置刷新完成以后,headerview固定的时间
+ xRefreshView.setPinnedTime(1000);
+ xRefreshView.setPullLoadEnable(true);
+ xRefreshView.setMoveForHorizontal(true);
+ xRefreshView.setAutoLoadMore(true);
+ //两种方式设置空布局,传入空布局的view或者传入布局id都可以
+// TextView textView = new TextView(this);
+// textView.setText("没有数据,点击刷新");
+// textView.setGravity(Gravity.CENTER);
+// xRefreshView.setEmptyView(textView);
+ xRefreshView.setEmptyView(R.layout.layout_emptyview);
+ xRefreshView.setXRefreshViewListener(listener);
+ }
+
+ private void requestScrllViewData() {
+ for (int i = 0; i < 50; i++) {
+ TextView tv = new TextView(this);
+ tv.setTextSize(16);
+ int padding = DensityUtil.dip2px(this, 20);
+ tv.setPadding(padding, padding, 0, 0);
+ tv.setTextIsSelectable(true);
+ tv.setText("数据" + i);
+ linearLayout.addView(tv);
+ }
+ }
+
+ private void requestRecyclerViewData() {
+ personList.clear();
+ for (int i = 0; i < 6; i++) {
+ Person person = new Person("name" + i, "" + i);
+ personList.add(person);
+ }
+ recyclerviewAdapter.setData(personList);
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ // 加载菜单
+ getMenuInflater().inflate(R.menu.menu_empty, menu);
+ return true;
+ }
+
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ int menuId = item.getItemId();
+ boolean showingRecyclerView = xRefreshView1.getVisibility() == View.VISIBLE;
+ switch (menuId) {
+ case R.id.menu_change:
+ xRefreshView1.setVisibility(showingRecyclerView ? View.GONE : View.VISIBLE);
+ xRefreshView2.setVisibility(showingRecyclerView ? View.VISIBLE : View.GONE);
+ toast(showingRecyclerView ? "切换至ScrollView" : "切换至Recyclerview");
+ break;
+ case R.id.menu_clear_or_fill:
+ if (showingRecyclerView) {
+ if (recyclerviewAdapter.getAdapterItemCount() != 0) {
+ recyclerviewAdapter.clear();
+ } else {
+ requestRecyclerViewData();
+ }
+ } else {
+ //非Recyclerview得在有数据和没有数据的时候,手动调用enableEmptyView方法来显示和关闭emptyView。
+ xRefreshView2.enableEmptyView(!xRefreshView2.isEmptyViewShowing());
+ }
+ break;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ private void toast(String msg) {
+ Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/andview/example/activity/GridViewActivity.java b/app/src/main/java/com/andview/example/activity/GridViewActivity.java
index 9d852bc..97ed3ff 100644
--- a/app/src/main/java/com/andview/example/activity/GridViewActivity.java
+++ b/app/src/main/java/com/andview/example/activity/GridViewActivity.java
@@ -17,105 +17,117 @@
import java.util.ArrayList;
import java.util.List;
+import java.util.Random;
public class GridViewActivity extends Activity {
- private GridView gv;
- private List str_name = new ArrayList();
- private XRefreshView outView;
- private ArrayAdapter adapter;
+ private GridView gv;
+ private List str_name = new ArrayList();
+ private XRefreshView xRefreshView;
+ private ArrayAdapter adapter;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_gridview);
- for (int i = 0; i < 50; i++) {
- str_name.add("数据" + i);
- }
- gv = (GridView) findViewById(R.id.gv);
- outView = (XRefreshView) findViewById(R.id.custom_view);
- outView.setPullLoadEnable(true);
- //设置在上拉加载被禁用的情况下,是否允许界面被上拉
-// outView.setMoveFootWhenDisablePullLoadMore(false);
- adapter = new ArrayAdapter(this,
- android.R.layout.simple_list_item_1, str_name);
- gv.setAdapter(adapter);
- outView.setPinnedTime(1000);
-// outView.setAutoLoadMore(true);
-// outView.setCustomHeaderView(new CustomHeader(this));
-// outView.setCustomHeaderView(new XRefreshViewHeader(this));
- outView.setMoveForHorizontal(true);
- outView.setCustomFooterView(new CustomerFooter(this));
-// outView.setPinnedContent(true);
- outView.setXRefreshViewListener(new SimpleXRefreshListener() {
- @Override
- public void onRefresh() {
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_gridview);
+ for (int i = 0; i < 50; i++) {
+ str_name.add("数据" + i);
+ }
+ gv = (GridView) findViewById(R.id.gv);
+ xRefreshView = (XRefreshView) findViewById(R.id.custom_view);
+ xRefreshView.setPullLoadEnable(true);
+ //设置在上拉加载被禁用的情况下,是否允许界面被上拉
+// xRefreshView.setMoveFootWhenDisablePullLoadMore(false);
+ adapter = new ArrayAdapter(this,
+ android.R.layout.simple_list_item_1, str_name);
+ gv.setAdapter(adapter);
+ xRefreshView.setPinnedTime(1000);
+ xRefreshView.setAutoLoadMore(false);
+// xRefreshView.setCustomHeaderView(new CustomHeader(this));
+// xRefreshView.setCustomHeaderView(new XRefreshViewHeader(this));
+ xRefreshView.setMoveForHorizontal(true);
+ xRefreshView.setCustomFooterView(new CustomerFooter(this));
+// xRefreshView.setPinnedContent(true);
+ //设置当非RecyclerView上拉加载完成以后的回弹时间
+ xRefreshView.setScrollBackDuration(300);
+ xRefreshView.setXRefreshViewListener(new SimpleXRefreshListener() {
+ @Override
+ public void onRefresh(boolean isPullDown) {
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- outView.stopRefresh();
- }
- }, 2000);
- }
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ //模拟数据加载失败的情况
+ Random random = new Random();
+ boolean success = random.nextBoolean();
+ if (success) {
+ xRefreshView.stopRefresh();
+ } else {
+ xRefreshView.stopRefresh(false);
+ }
+ //或者
+// xRefreshView.stopRefresh(success);
+ }
+ }, 2000);
+ }
- @Override
- public void onLoadMore(boolean isSlience) {
- final List addlist = new ArrayList();
- for (int i = 0; i < 20; i++) {
- addlist.add("数据" + (i + str_name.size()));
- }
+ @Override
+ public void onLoadMore(boolean isSilence) {
+ final List addlist = new ArrayList();
+ for (int i = 0; i < 20; i++) {
+ addlist.add("数据" + (i + str_name.size()));
+ }
- new Handler().postDelayed(new Runnable() {
+ new Handler().postDelayed(new Runnable() {
- @SuppressLint("NewApi")
- @Override
- public void run() {
- if (str_name.size() <= 90) {
- if (Build.VERSION.SDK_INT >= 11) {
- adapter.addAll(addlist);
- }
- outView.stopLoadMore();
- } else {
- outView.setLoadComplete(true);
- }
- }
- }, 2000);
- }
- });
- }
+ @SuppressLint("NewApi")
+ @Override
+ public void run() {
+ if (str_name.size() <= 90) {
+ if (Build.VERSION.SDK_INT >= 11) {
+ adapter.addAll(addlist);
+ }
+ xRefreshView.stopLoadMore();
+ } else {
+ xRefreshView.setLoadComplete(true);
+ }
+ }
+ }, 2000);
+ }
+ });
+ }
- @Override
- protected void onResume() {
- super.onResume();
- outView.startRefresh();
- }
+ @Override
+ protected void onResume() {
+ super.onResume();
+ xRefreshView.startRefresh();
+ }
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- // 加载菜单
- getMenuInflater().inflate(R.menu.main, menu);
- return true;
- }
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ // 加载菜单
+ getMenuInflater().inflate(R.menu.main, menu);
+ return true;
+ }
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- int menuId = item.getItemId();
- switch (menuId) {
- case R.id.menu_clear:
- str_name.clear();
- for (int i = 0; i < 50; i++) {
- str_name.add("数据" + i);
- }
- adapter.notifyDataSetChanged();
- outView.setLoadComplete(false);
- break;
- case R.id.menu_refresh:
- outView.startRefresh();
- break;
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ int menuId = item.getItemId();
+ switch (menuId) {
+ case R.id.menu_clear:
+ str_name.clear();
+ for (int i = 0; i < 50; i++) {
+ str_name.add("数据" + i);
+ }
+ adapter.notifyDataSetChanged();
+ xRefreshView.setLoadComplete(false);
+ break;
+ case R.id.menu_refresh:
+ xRefreshView.startRefresh();
+ break;
- default:
- break;
- }
- return super.onOptionsItemSelected(item);
- }
+ default:
+ break;
+ }
+ return super.onOptionsItemSelected(item);
+ }
}
diff --git a/app/src/main/java/com/andview/example/activity/HeadAdActivity.java b/app/src/main/java/com/andview/example/activity/HeadAdActivity.java
index 429b479..6c15409 100644
--- a/app/src/main/java/com/andview/example/activity/HeadAdActivity.java
+++ b/app/src/main/java/com/andview/example/activity/HeadAdActivity.java
@@ -55,10 +55,10 @@ public void onCreate(Bundle savedInstanceState) {
outView.setCustomFooterView(new CustomerFooter(this));
// outView.setCustomHeaderView(new XRefreshViewHeader(this));
outView.setMoveForHorizontal(true);
- outView.setPinnedContent(true);
+// outView.setPinnedContent(true);
outView.setXRefreshViewListener(new SimpleXRefreshListener() {
@Override
- public void onRefresh() {
+ public void onRefresh(boolean isPullDown) {
new Handler().postDelayed(new Runnable() {
@Override
@@ -69,7 +69,7 @@ public void run() {
}
@Override
- public void onLoadMore(boolean isSlience) {
+ public void onLoadMore(boolean isSilence) {
final List addlist = new ArrayList();
for (int i = 0; i < 20; i++) {
addlist.add("数据" + (i + str_name.size()));
diff --git a/app/src/main/java/com/andview/example/activity/JDActivity.java b/app/src/main/java/com/andview/example/activity/JDActivity.java
new file mode 100644
index 0000000..907a664
--- /dev/null
+++ b/app/src/main/java/com/andview/example/activity/JDActivity.java
@@ -0,0 +1,153 @@
+package com.andview.example.activity;
+
+import android.animation.Animator;
+import android.animation.ObjectAnimator;
+import android.graphics.drawable.AnimationDrawable;
+import android.os.Bundle;
+import android.app.Activity;
+import android.os.Handler;
+import android.util.Log;
+import android.view.View;
+import android.view.animation.Animation;
+import android.view.animation.AnimationSet;
+import android.view.animation.ScaleAnimation;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.SeekBar;
+
+import com.andview.example.R;
+import com.andview.example.view.XRefreshViewJDHeader;
+import com.andview.example.view.XRefreshViewWineHeader;
+import com.andview.refreshview.XRefreshView;
+
+public class JDActivity extends Activity {
+ private final static String TAG = JDActivity.class.getSimpleName();
+
+ private ImageView ivPerson;
+ private ImageView ivPackage;
+
+ private Button btnPackageScan;
+ private Button btnPersonScan;
+
+ private SeekBar jdSeekBar;
+
+ private XRefreshView jdXRefreshView;
+
+ private float startPoint = 0;
+ private float endPoint = 0;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_jd);
+ initView();
+ initData();
+ }
+
+ private void initView() {
+ ivPerson = (ImageView) findViewById(R.id.ivPerson);
+ ivPackage = (ImageView) findViewById(R.id.ivPackage);
+
+ btnPackageScan = (Button) findViewById(R.id.btnPackageScan);
+ btnPersonScan = (Button) findViewById(R.id.btnPersonScan);
+
+ jdSeekBar = (SeekBar) findViewById(R.id.jdSeekBar);
+
+ jdXRefreshView = (XRefreshView) findViewById(R.id.jdXRefreshView);
+ jdXRefreshView.setCustomHeaderView(new XRefreshViewJDHeader(this));
+ jdXRefreshView.setMoveForHorizontal(true);
+ }
+
+ private void initData() {
+
+ btnPackageScan.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ packageScan();
+ }
+ });
+
+ btnPersonScan.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ personScan();
+ }
+ });
+
+
+ jdSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+ @Override
+ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+ startPoint = endPoint;
+ endPoint = (float) progress / 100f;
+ if (endPoint != 1f) {
+ ivPackage.setImageResource(R.drawable.jd_package);
+ ivPerson.setImageResource(R.drawable.jd_person);
+ }
+
+ ScaleAnimation scaleAnimation = new ScaleAnimation(startPoint, endPoint, startPoint, endPoint, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
+ scaleAnimation.setFillAfter(true);
+ ivPackage.startAnimation(scaleAnimation);
+
+ ScaleAnimation scaleAnimationPerson = new ScaleAnimation(startPoint, endPoint, startPoint, endPoint, Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0.5f);
+ scaleAnimationPerson.setFillAfter(true);
+ ivPerson.startAnimation(scaleAnimationPerson);
+
+ if (startPoint != endPoint) {
+ startPoint = endPoint;
+ }
+
+ if (endPoint == 1f) {
+ ivPackage.setImageDrawable(null);
+ ivPerson.setImageResource(R.drawable.jd_loading);
+ ((AnimationDrawable) ivPerson.getDrawable()).start();
+
+ }
+
+ Log.d(TAG, "滑动初始距离:" + startPoint);
+ Log.d(TAG, "滑动结束比例:" + endPoint);
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {
+
+ }
+
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {
+
+ }
+ });
+
+
+ jdXRefreshView.setAutoRefresh(false);
+ jdXRefreshView.setPullRefreshEnable(true);
+ jdXRefreshView.setMoveForHorizontal(true);
+ jdXRefreshView.setXRefreshViewListener(new XRefreshView.SimpleXRefreshListener() {
+ @Override
+ public void onRefresh(boolean isPullDown) {
+ super.onRefresh(isPullDown);
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ jdXRefreshView.stopRefresh();
+ }
+ }, 1000);
+ }
+ });
+ }
+
+ private void packageScan() {
+ ScaleAnimation scaleAnimation = new ScaleAnimation(0f, 1f, 0f, 1f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
+ scaleAnimation.setDuration(1000);
+ ivPackage.startAnimation(scaleAnimation);
+ }
+
+ private void personScan() {
+ ScaleAnimation scaleAnimation = new ScaleAnimation(0f, 1f, 0f, 1f, Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0.5f);
+ scaleAnimation.setDuration(1000);
+ ivPerson.startAnimation(scaleAnimation);
+ }
+
+
+}
diff --git a/app/src/main/java/com/andview/example/activity/ListViewActivity.java b/app/src/main/java/com/andview/example/activity/ListViewActivity.java
index a08a780..4854a42 100644
--- a/app/src/main/java/com/andview/example/activity/ListViewActivity.java
+++ b/app/src/main/java/com/andview/example/activity/ListViewActivity.java
@@ -10,44 +10,44 @@
import android.widget.Toast;
import com.andview.example.R;
-import com.andview.example.ui.raindrop.CustomerFooter;
import com.andview.refreshview.XRefreshView;
import com.andview.refreshview.XRefreshView.SimpleXRefreshListener;
-import com.andview.refreshview.listener.OnBottomLoadMoreTime;
import com.andview.refreshview.utils.LogUtils;
import java.util.ArrayList;
import java.util.List;
public class ListViewActivity extends Activity {
- private ListView lv;
- private List str_name = new ArrayList();
- private XRefreshView refreshView;
- private ArrayAdapter adapter;
- public static long lastRefreshTime;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_listview);
- for (int i = 0; i < 30; i++) {
- str_name.add("数据" + i);
- }
- lv = (ListView) findViewById(R.id.lv);
- refreshView = (XRefreshView) findViewById(R.id.custom_view);
-
- adapter = new ArrayAdapter(this,
- android.R.layout.simple_list_item_1, str_name);
- lv.setAdapter(adapter);
-
- // 设置是否可以下拉刷新
- refreshView.setPullRefreshEnable(false);
- // 设置是否可以上拉加载
- refreshView.setPullLoadEnable(false);
- // 设置上次刷新的时间
- refreshView.restoreLastRefreshTime(lastRefreshTime);
- // 设置时候可以自动刷新
- refreshView.setAutoRefresh(false);
+ private ListView lv;
+ private List str_name = new ArrayList();
+ private XRefreshView refreshView;
+ private ArrayAdapter adapter;
+ public static long lastRefreshTime;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_listview);
+ for (int i = 0; i < 3; i++) {
+ str_name.add("数据" + i);
+ }
+ lv = (ListView) findViewById(R.id.lv);
+ refreshView = (XRefreshView) findViewById(R.id.custom_view);
+
+ adapter = new ArrayAdapter(this,
+ android.R.layout.simple_list_item_1, str_name);
+ lv.setAdapter(adapter);
+
+ // 设置是否可以下拉刷新
+ refreshView.setPullRefreshEnable(false);
+ // 设置是否可以上拉加载
+ refreshView.setPullLoadEnable(false);
+ // 设置上次刷新的时间
+ refreshView.restoreLastRefreshTime(lastRefreshTime);
+ //当下拉刷新被禁用时,调用这个方法并传入false可以不让头部被下拉
+ refreshView.setMoveHeadWhenDisablePullRefresh(true);
+ // 设置时候可以自动刷新
+ refreshView.setAutoRefresh(false);
// refreshView.setOnBottomLoadMoreTime(new OnBottomLoadMoreTime() {
// @Override
// public boolean isBottom() {
@@ -55,59 +55,57 @@ public void onCreate(Bundle savedInstanceState) {
// }
// });
- refreshView.setXRefreshViewListener(new SimpleXRefreshListener() {
-
- @Override
- public void onRefresh() {
-
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- refreshView.stopRefresh();
- lastRefreshTime = refreshView.getLastRefreshTime();
- }
- }, 2000);
- }
-
- @Override
- public void onLoadMore(boolean isSlience) {
- new Handler().postDelayed(new Runnable() {
-
- @Override
- public void run() {
- refreshView.stopLoadMore();
- }
- }, 2000);
- }
-
- @Override
- public void onRelease(float direction) {
- super.onRelease(direction);
- if (direction > 0) {
- toast("下拉");
- } else {
- toast("上拉");
- }
- }
- });
- refreshView.setOnAbsListViewScrollListener(new OnScrollListener() {
-
- @Override
- public void onScrollStateChanged(AbsListView view, int scrollState) {
- LogUtils.i("onScrollStateChanged");
- }
-
- @Override
- public void onScroll(AbsListView view, int firstVisibleItem,
- int visibleItemCount, int totalItemCount) {
- LogUtils.i("onScroll");
- }
- });
-
- }
-
- public void toast(String msg) {
- Toast.makeText(getApplicationContext(), msg, 0).show();
- }
+ refreshView.setXRefreshViewListener(new SimpleXRefreshListener() {
+ @Override
+ public void onRefresh(boolean isPullDown) {
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ refreshView.stopRefresh();
+ lastRefreshTime = refreshView.getLastRefreshTime();
+ }
+ }, 2000);
+ }
+
+ @Override
+ public void onLoadMore(boolean isSilence) {
+ new Handler().postDelayed(new Runnable() {
+
+ @Override
+ public void run() {
+ refreshView.stopLoadMore();
+ }
+ }, 2000);
+ }
+
+ @Override
+ public void onRelease(float direction) {
+ super.onRelease(direction);
+ if (direction > 0) {
+ toast("下拉");
+ } else {
+ toast("上拉");
+ }
+ }
+ });
+ refreshView.setOnAbsListViewScrollListener(new OnScrollListener() {
+
+ @Override
+ public void onScrollStateChanged(AbsListView view, int scrollState) {
+ LogUtils.i("onScrollStateChanged");
+ }
+
+ @Override
+ public void onScroll(AbsListView view, int firstVisibleItem,
+ int visibleItemCount, int totalItemCount) {
+ LogUtils.i("onScroll");
+ }
+ });
+
+ }
+
+ public void toast(String msg) {
+ Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/andview/example/activity/MainActivity.java b/app/src/main/java/com/andview/example/activity/MainActivity.java
index 68b55dc..3b28807 100644
--- a/app/src/main/java/com/andview/example/activity/MainActivity.java
+++ b/app/src/main/java/com/andview/example/activity/MainActivity.java
@@ -6,6 +6,8 @@
import android.view.View;
import com.andview.example.R;
+import com.andview.example.view.EatPluseView;
+import com.andview.refreshview.utils.LogUtils;
public class MainActivity extends Activity {
@@ -13,6 +15,8 @@ public class MainActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
+ //如果不想XRefreshView后台输出log,此处传入false即可
+ LogUtils.enableLog(true);
}
public void onClick(View v) {
@@ -42,9 +46,31 @@ public void onClick(View v) {
case R.id.bt_not_full_screen:
intent = new Intent(this, NotFullScreenActivity.class);
break;
+ case R.id.bt_not_fullscreen_nofooter:
+ intent = new Intent(this, NotFullScreenWithoutFooterActivity.class);
+ break;
+ case R.id.bt_emptyview:
+ intent = new Intent(this, EmptyViewActivity.class);
+ break;
+ case R.id.bt_smileview:
+ intent = new Intent(this, SmileViewActivity.class);
+ break;
case R.id.bt_rain:
// intent = new Intent(this, RainDropActivity.class);
break;
+
+ case R.id.bt_wine:
+ intent = new Intent(this, WineActivity.class);
+ break;
+ case R.id.bt_jd:
+ intent = new Intent(this, JDActivity.class);
+ break;
+ case R.id.bt_carcrm:
+ intent = new Intent(this, CarCrmActivity.class);
+ break;
+ case R.id.bt_pluse:
+ intent = new Intent(this, PluseActivity.class);
+ break;
default:
break;
}
diff --git a/app/src/main/java/com/andview/example/activity/NotFullScreenActivity.java b/app/src/main/java/com/andview/example/activity/NotFullScreenActivity.java
index 38e9d81..095a35d 100644
--- a/app/src/main/java/com/andview/example/activity/NotFullScreenActivity.java
+++ b/app/src/main/java/com/andview/example/activity/NotFullScreenActivity.java
@@ -3,11 +3,13 @@
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
-import android.support.v7.widget.GridLayoutManager;
-import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
import android.view.Menu;
import android.view.MenuItem;
+import android.view.View;
+
+import androidx.recyclerview.widget.GridLayoutManager;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
import com.andview.example.R;
import com.andview.example.recylerview.Person;
@@ -43,7 +45,7 @@ protected void onCreate(Bundle savedInstanceState) {
adapter = new SimpleAdapter(personList, this);
// 设置静默加载模式
-// xRefreshView.setSilenceLoadMore();
+// xRefreshView1.setSilenceLoadMore();
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
// 静默加载模式不能设置footerview
@@ -53,14 +55,17 @@ protected void onCreate(Bundle savedInstanceState) {
xRefreshView.setPullLoadEnable(true);
xRefreshView.setMoveForHorizontal(true);
xRefreshView.setAutoLoadMore(true);
+ xRefreshView.setEmptyView(R.layout.layout_emptyview);
+ showXRefreshView(false);
+
adapter.setCustomLoadMoreView(new XRefreshViewFooter(this));
//设置静默加载时提前加载的item个数
-// xRefreshView.setPreLoadCount(4);
+// xRefreshView1.setPreLoadCount(4);
xRefreshView.setXRefreshViewListener(new SimpleXRefreshListener() {
@Override
- public void onRefresh() {
+ public void onRefresh(boolean isPullDown) {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
@@ -70,14 +75,15 @@ public void run() {
}
@Override
- public void onLoadMore(boolean isSlience) {
+ public void onLoadMore(boolean isSilence) {
+ LogUtils.e("loadmore");
new Handler().postDelayed(new Runnable() {
public void run() {
for (int i = 0; i < 1; i++) {
adapter.insert(new Person("More ", mLoadCount + "21"),
adapter.getAdapterItemCount());
}
- LogUtils.i("test onLoadMore adapter.count="+adapter.getItemCount());
+ LogUtils.i("test onLoadMore recyclerviewAdapter.count=" + adapter.getItemCount());
mLoadCount++;
if (mLoadCount >= 5) {
@@ -91,10 +97,10 @@ public void run() {
}
});
//如果想在数据加载完成以后不隐藏footerview则需要调用下面这行代码并传入false
-// xRefreshView.setHideFooterWhenComplete(false);
+// xRefreshView1.setHideFooterWhenComplete(false);
requestData();
// // 实现Recyclerview的滚动监听
-// xRefreshView.setOnRecyclerViewScrollListener(new OnScrollListener() {
+// xRefreshView1.setOnRecyclerViewScrollListener(new OnScrollListener() {
// @Override
// public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
// super.onScrolled(recyclerView, dx, dy);
@@ -104,12 +110,16 @@ public void run() {
// public void onScrollStateChanged(RecyclerView recyclerView,
// int newState) {
// if (newState == RecyclerView.SCROLL_STATE_IDLE) {
-// isBottom = adapter.getItemCount() - 1 == lastVisibleItem;
+// isBottom = recyclerviewAdapter.getItemCount() - 1 == lastVisibleItem;
// }
// }
// });
}
+ public void showXRefreshView(boolean show) {
+ xRefreshView.setVisibility(show ? View.VISIBLE : View.GONE);
+ }
+
public void requestData() {
new Handler().postDelayed(new Runnable() {
@Override
@@ -124,6 +134,7 @@ private void initData() {
for (int i = 0; i < 1; i++) {
Person person = new Person("name" + i, "" + i);
personList.add(person);
+ showXRefreshView(true);
}
}
diff --git a/app/src/main/java/com/andview/example/activity/NotFullScreenWithoutFooterActivity.java b/app/src/main/java/com/andview/example/activity/NotFullScreenWithoutFooterActivity.java
new file mode 100644
index 0000000..6588b43
--- /dev/null
+++ b/app/src/main/java/com/andview/example/activity/NotFullScreenWithoutFooterActivity.java
@@ -0,0 +1,156 @@
+package com.andview.example.activity;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.andview.example.R;
+import com.andview.example.recylerview.Person;
+import com.andview.example.recylerview.SimpleAdapter;
+import com.andview.example.ui.CustomFooterView;
+import com.andview.refreshview.XRefreshView;
+import com.andview.refreshview.XRefreshView.SimpleXRefreshListener;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class NotFullScreenWithoutFooterActivity extends Activity {
+ RecyclerView recyclerView;
+ SimpleAdapter adapter;
+ List personList = new ArrayList();
+ XRefreshView xRefreshView;
+ // GridLayoutManager layoutManager;
+ LinearLayoutManager layoutManager;
+ private int mLoadCount = 0;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_recylerview2);
+ xRefreshView = (XRefreshView) findViewById(R.id.xrefreshview);
+ xRefreshView.setPullLoadEnable(true);
+ recyclerView = (RecyclerView) findViewById(R.id.recycler_view_test_rv);
+ recyclerView.setHasFixedSize(true);
+
+ adapter = new SimpleAdapter(personList, this);
+ // 设置静默加载模式
+// xRefreshView1.setSilenceLoadMore();
+ layoutManager = new LinearLayoutManager(this);
+ recyclerView.setLayoutManager(layoutManager);
+ // 静默加载模式不能设置footerview
+ recyclerView.setAdapter(adapter);
+ //设置刷新完成以后,headerview固定的时间
+ xRefreshView.setPinnedTime(1000);
+ xRefreshView.setPullLoadEnable(true);
+ xRefreshView.setMoveForHorizontal(true);
+ xRefreshView.setAutoLoadMore(true);
+ xRefreshView.setEmptyView(R.layout.layout_emptyview);
+ xRefreshView.getEmptyView().setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ xRefreshView.startRefresh();
+ }
+ });
+ //设置静默加载时提前加载的item个数
+// xRefreshView1.setPreLoadCount(4);
+
+ xRefreshView.setXRefreshViewListener(new SimpleXRefreshListener() {
+
+ @Override
+ public void onRefresh(boolean isPullDown) {
+ requestData();
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ xRefreshView.stopRefresh();
+ }
+ }, 1000);
+ }
+
+ @Override
+ public void onLoadMore(boolean isSilence) {
+ new Handler().postDelayed(new Runnable() {
+ public void run() {
+ for (int i = 0; i < 1; i++) {
+ adapter.insert(new Person("More ", mLoadCount + "21"),
+ adapter.getAdapterItemCount());
+ }
+ mLoadCount++;
+
+ if (mLoadCount >= 5) {
+ xRefreshView.setLoadComplete(true);
+ } else {
+ // 刷新完成必须调用此方法停止加载
+ xRefreshView.stopLoadMore();
+ }
+ }
+ }, 1000);
+ }
+ });
+ //如果想在数据加载完成以后不隐藏footerview则需要调用下面这行代码并传入false
+// xRefreshView1.setHideFooterWhenComplete(false);
+ requestData();
+// // 实现Recyclerview的滚动监听
+// xRefreshView1.setOnRecyclerViewScrollListener(new OnScrollListener() {
+// @Override
+// public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
+// super.onScrolled(recyclerView, dx, dy);
+// lastVisibleItem = layoutManager.findLastVisibleItemPosition();
+// }
+//
+// public void onScrollStateChanged(RecyclerView recyclerView,
+// int newState) {
+// if (newState == RecyclerView.SCROLL_STATE_IDLE) {
+// isBottom = recyclerviewAdapter.getItemCount() - 1 == lastVisibleItem;
+// }
+// }
+// });
+ }
+
+ public void requestData() {
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ if (adapter.getCustomLoadMoreView() == null) {
+ adapter.setCustomLoadMoreView(new CustomFooterView(NotFullScreenWithoutFooterActivity.this));
+ }
+ addData();
+ adapter.setData(personList);
+ }
+ }, 1000);
+ }
+
+ private void addData() {
+ for (int i = 0; i < 3; i++) {
+ Person person = new Person("name" + i, "" + i);
+ personList.add(person);
+ }
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ // 加载菜单
+ getMenuInflater().inflate(R.menu.main, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ int menuId = item.getItemId();
+ switch (menuId) {
+ case R.id.menu_clear:
+ xRefreshView.setLoadComplete(false);
+ break;
+ case R.id.menu_refresh:
+ xRefreshView.startRefresh();
+ break;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/andview/example/activity/PluseActivity.java b/app/src/main/java/com/andview/example/activity/PluseActivity.java
new file mode 100644
index 0000000..061379c
--- /dev/null
+++ b/app/src/main/java/com/andview/example/activity/PluseActivity.java
@@ -0,0 +1,16 @@
+package com.andview.example.activity;
+
+import android.os.Bundle;
+import android.app.Activity;
+
+import com.andview.example.R;
+
+public class PluseActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_pluse);
+ }
+
+}
diff --git a/app/src/main/java/com/andview/example/activity/RainDropActivity.java b/app/src/main/java/com/andview/example/activity/RainDropActivity.java
index 0897188..7b039a9 100644
--- a/app/src/main/java/com/andview/example/activity/RainDropActivity.java
+++ b/app/src/main/java/com/andview/example/activity/RainDropActivity.java
@@ -19,7 +19,7 @@ public class RainDropActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_scrollview);
+ setContentView(R.layout.adapter_scrollview);
outView = (XRefreshView) findViewById(R.id.custom_view);
ll = (LinearLayout) findViewById(R.id.ll);
@@ -30,7 +30,7 @@ public void onCreate(Bundle savedInstanceState) {
outView.setXRefreshViewListener(new SimpleXRefreshListener() {
@Override
- public void onRefresh() {
+ public void onRefresh(boolean isPullDown) {
new Handler().postDelayed(new Runnable() {
@Override
@@ -41,7 +41,7 @@ public void run() {
}
@Override
- public void onLoadMore(boolean isSlience) {
+ public void onLoadMore(boolean isSilence) {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
diff --git a/app/src/main/java/com/andview/example/activity/RecyclerViewsActivity.java b/app/src/main/java/com/andview/example/activity/RecyclerViewsActivity.java
index 1284ce7..5d330d9 100644
--- a/app/src/main/java/com/andview/example/activity/RecyclerViewsActivity.java
+++ b/app/src/main/java/com/andview/example/activity/RecyclerViewsActivity.java
@@ -6,6 +6,14 @@
import android.view.View;
import com.andview.example.R;
+import com.andview.example.activity.recyclerview.BannerRecyclerViewActivity;
+import com.andview.example.activity.recyclerview.GridRecyclerViewActivity;
+import com.andview.example.activity.recyclerview.LinearRecyclerViewActivity;
+import com.andview.example.activity.recyclerview.MultiItemRecyclerViewActivity;
+import com.andview.example.activity.recyclerview.ShowFooterWhenNoMoreDataRecyclerViewActivity;
+import com.andview.example.activity.recyclerview.SilenceRecyclerViewActivity;
+import com.andview.example.activity.recyclerview.StaggeredRecyclerViewActivity;
+import com.andview.example.activity.recyclerview.WithoutBaseAdapterRecyclerViewActivity;
public class RecyclerViewsActivity extends Activity {
@@ -36,6 +44,12 @@ public void onClick(View v) {
case R.id.bt_multi_item:
intent = new Intent(this, MultiItemRecyclerViewActivity.class);
break;
+ case R.id.bt_without_baseRecyclerAdapter:
+ intent = new Intent(this, WithoutBaseAdapterRecyclerViewActivity.class);
+ break;
+ case R.id.bt_showFooter_noMoreData:
+ intent = new Intent(this, ShowFooterWhenNoMoreDataRecyclerViewActivity.class);
+ break;
default:
break;
}
diff --git a/app/src/main/java/com/andview/example/activity/ScrollViewActivity.java b/app/src/main/java/com/andview/example/activity/ScrollViewActivity.java
index 36822db..8bb6968 100644
--- a/app/src/main/java/com/andview/example/activity/ScrollViewActivity.java
+++ b/app/src/main/java/com/andview/example/activity/ScrollViewActivity.java
@@ -2,71 +2,25 @@
import android.app.Activity;
import android.os.Bundle;
-import android.os.Handler;
import android.view.Menu;
import android.view.MenuItem;
-import android.widget.LinearLayout;
-import android.widget.TextView;
+
+import androidx.viewpager.widget.ViewPager;
import com.andview.example.R;
-import com.andview.example.ui.raindrop.CustomerFooter;
-import com.andview.refreshview.XRefreshView;
-import com.andview.refreshview.XRefreshView.SimpleXRefreshListener;
+import com.andview.example.ScrollAdapter;
public class ScrollViewActivity extends Activity {
- private XRefreshView outView;
- private LinearLayout ll;
- private int count = 1;
+ private ViewPager mViewPager;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scrollview);
- outView = (XRefreshView) findViewById(R.id.custom_view);
- ll = (LinearLayout) findViewById(R.id.ll);
- outView.setAutoRefresh(false);
- outView.setPullLoadEnable(true);
- outView.setPinnedTime(1000);
- outView.setAutoLoadMore(true);
-// outView.setAutoLoadMore(true);
-// outView.setSilenceLoadMore();
- outView.setCustomFooterView(new CustomerFooter(this));
-
- outView.setXRefreshViewListener(new SimpleXRefreshListener() {
-
- @Override
- public void onRefresh() {
+ mViewPager = (ViewPager) findViewById(R.id.index_viewpager);
+ ScrollAdapter adapter = new ScrollAdapter(this);
+ mViewPager.setAdapter(adapter);
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- outView.stopRefresh();
- }
- }, 2000);
- }
-
- @Override
- public void onLoadMore(boolean isSlience) {
- new Handler().postDelayed(new Runnable() {
- @Override
- public void run() {
- //setLoadComplete不要和stopLoadMore同时调用
- if (count > 100) {
- outView.setLoadComplete(true);
- } else {
- outView.stopLoadMore();
- }
- count++;
- }
- }, 2000);
- }
- });
- for (int i = 0; i < 50; i++) {
- TextView tv = new TextView(this);
- tv.setTextIsSelectable(true);
- tv.setText("数据" + i);
- ll.addView(tv);
- }
}
@Override
@@ -78,23 +32,6 @@ public boolean onCreateOptionsMenu(Menu menu) {
@Override
public boolean onOptionsItemSelected(MenuItem item) {
- int menuId = item.getItemId();
- switch (menuId) {
- case R.id.menu_clear:
- outView.setPullLoadEnable(!outView.getPullLoadEnable());
- break;
- case R.id.menu_refresh:
- outView.startRefresh();
- break;
-
- default:
- break;
- }
return super.onOptionsItemSelected(item);
}
-// @Override
-// protected void onResume() {
-// super.onResume();
-// outView.startRefresh();
-// }
}
diff --git a/app/src/main/java/com/andview/example/activity/SmileViewActivity.java b/app/src/main/java/com/andview/example/activity/SmileViewActivity.java
new file mode 100644
index 0000000..0150917
--- /dev/null
+++ b/app/src/main/java/com/andview/example/activity/SmileViewActivity.java
@@ -0,0 +1,124 @@
+package com.andview.example.activity;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.View;
+import android.widget.AbsListView;
+import android.widget.AbsListView.OnScrollListener;
+
+import com.andview.example.R;
+import com.andview.example.StickyListBean;
+import com.andview.example.StickylistAdapter;
+import com.andview.example.stickyListHeaders.StickyListHeadersListView;
+import com.andview.example.ui.raindrop.CustomerFooter;
+import com.andview.example.ui.smileyloadingview.SmileyHeaderView;
+import com.andview.refreshview.XRefreshView;
+import com.andview.refreshview.listener.OnBottomLoadMoreTime;
+import com.andview.refreshview.listener.OnTopRefreshTime;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class SmileViewActivity extends Activity {
+ private StickyListHeadersListView stickyLv;
+ private List list = new ArrayList();
+ private XRefreshView refreshView;
+ private int mTotalItemCount;
+ private StickylistAdapter adapter;
+ private final int mPinnedTime = 1000;
+
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_customview);
+ initData();
+ stickyLv = (StickyListHeadersListView) findViewById(R.id.sticky_list);
+ adapter = new StickylistAdapter(getApplicationContext(), list);
+ stickyLv.setAdapter(adapter);
+ refreshView = (XRefreshView) findViewById(R.id.custom_view);
+ refreshView.setPullLoadEnable(true);
+ refreshView.setPinnedTime(mPinnedTime);
+ refreshView.setCustomHeaderView(new SmileyHeaderView(this));
+ refreshView.setCustomFooterView(new CustomerFooter(SmileViewActivity.this));
+ refreshView.setOnTopRefreshTime(new OnTopRefreshTime() {
+
+ @Override
+ public boolean isTop() {
+ if (stickyLv.getFirstVisiblePosition() == 0) {
+ View firstVisibleChild = stickyLv.getListChildAt(0);
+ return firstVisibleChild.getTop() >= 0;
+ }
+ return false;
+ }
+ });
+ refreshView.setOnBottomLoadMoreTime(new OnBottomLoadMoreTime() {
+
+ @Override
+ public boolean isBottom() {
+ if (stickyLv.getLastVisiblePosition() == mTotalItemCount - 1) {
+ View lastChild = stickyLv.getListChildAt(stickyLv.getListChildCount() - 1);
+ return (lastChild.getBottom() + stickyLv.getPaddingBottom()) <= stickyLv.getMeasuredHeight();
+ }
+ return false;
+ }
+ });
+ stickyLv.setOnScrollListener(new OnScrollListener() {
+
+ @Override
+ public void onScrollStateChanged(AbsListView view, int scrollState) {
+
+ }
+
+ @Override
+ public void onScroll(AbsListView view, int firstVisibleItem,
+ int visibleItemCount, int totalItemCount) {
+ mTotalItemCount = totalItemCount;
+ }
+ });
+ refreshView.setXRefreshViewListener(new XRefreshView.SimpleXRefreshListener() {
+
+ @Override
+ public void onRefresh(boolean isPullDown) {
+
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ refreshView.stopRefresh();
+ }
+ }, 4000);
+ }
+
+ @Override
+ public void onLoadMore(boolean isSilence) {
+
+ new Handler().postDelayed(new Runnable() {
+
+ @Override
+ public void run() {
+ refreshView.stopLoadMore();
+ }
+ }, 2000);
+ }
+ });
+ }
+
+ int section = 0;
+ String YM = null;
+ String content = null;
+
+ private void initData() {
+
+ for (int i = 0; i < 20; i++) {
+ if (i % 5 == 0) {
+ section++;
+ YM = "第" + section + "个头";
+ }
+ content = "第" + i + "项数据";
+ StickyListBean bean = new StickyListBean(section, YM, content);
+ list.add(bean);
+ }
+
+ }
+}
diff --git a/app/src/main/java/com/andview/example/activity/TaoBaoActivity.java b/app/src/main/java/com/andview/example/activity/TaoBaoActivity.java
new file mode 100644
index 0000000..6a94bd7
--- /dev/null
+++ b/app/src/main/java/com/andview/example/activity/TaoBaoActivity.java
@@ -0,0 +1,16 @@
+package com.andview.example.activity;
+
+import android.os.Bundle;
+import android.app.Activity;
+
+import com.andview.example.R;
+
+public class TaoBaoActivity extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_tao_bao);
+ }
+
+}
diff --git a/app/src/main/java/com/andview/example/activity/WebViewActivity.java b/app/src/main/java/com/andview/example/activity/WebViewActivity.java
index 2c8c4d5..2819dee 100644
--- a/app/src/main/java/com/andview/example/activity/WebViewActivity.java
+++ b/app/src/main/java/com/andview/example/activity/WebViewActivity.java
@@ -10,6 +10,7 @@
import com.andview.example.ui.raindrop.CustomerFooter;
import com.andview.refreshview.XRefreshView;
import com.andview.refreshview.XRefreshView.SimpleXRefreshListener;
+import com.andview.refreshview.utils.LogUtils;
public class WebViewActivity extends Activity {
private XRefreshView outView;
@@ -30,6 +31,12 @@ public boolean shouldOverrideUrlLoading(WebView view, String url) {
return true;
}
+ @Override
+ public void onScaleChanged(WebView view, float oldScale, float newScale) {
+ super.onScaleChanged(view, oldScale, newScale);
+ LogUtils.e("oldScale="+oldScale+";newScale="+newScale);
+ }
+
@Override
public void onPageFinished(WebView view, String url) {
outView.stopRefresh();
@@ -44,12 +51,12 @@ public void onPageFinished(WebView view, String url) {
outView.setXRefreshViewListener(new SimpleXRefreshListener() {
@Override
- public void onRefresh() {
+ public void onRefresh(boolean isPullDown) {
mWebView.loadUrl("http://www.baidu.com");
}
@Override
- public void onLoadMore(boolean isSlience) {
+ public void onLoadMore(boolean isSilence) {
new Handler().postDelayed(new Runnable() {
@Override
diff --git a/app/src/main/java/com/andview/example/activity/WineActivity.java b/app/src/main/java/com/andview/example/activity/WineActivity.java
new file mode 100644
index 0000000..c258315
--- /dev/null
+++ b/app/src/main/java/com/andview/example/activity/WineActivity.java
@@ -0,0 +1,49 @@
+package com.andview.example.activity;
+
+import android.os.Bundle;
+import android.app.Activity;
+import android.os.Handler;
+
+import com.andview.example.DensityUtil;
+import com.andview.example.R;
+import com.andview.example.view.XRefreshViewWineHeader;
+import com.andview.refreshview.XRefreshView;
+
+public class WineActivity extends Activity {
+ private XRefreshView wineXRefreshView;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_wine);
+
+ initView();
+ initData();
+ }
+
+ private void initView() {
+ wineXRefreshView = (XRefreshView) findViewById(R.id.wineXRefreshView);
+ wineXRefreshView.setCustomHeaderView(new XRefreshViewWineHeader(this));
+ wineXRefreshView.setAddHeaderTop(true);
+ wineXRefreshView.setHeaderTopHeight(DensityUtil.dip2px(this, 212));
+ }
+
+ private void initData() {
+ wineXRefreshView.setAutoRefresh(false);
+ wineXRefreshView.setPullRefreshEnable(true);
+ wineXRefreshView.setMoveForHorizontal(true);
+ wineXRefreshView.setXRefreshViewListener(new XRefreshView.SimpleXRefreshListener() {
+ @Override
+ public void onRefresh(boolean isPullDown) {
+ super.onRefresh(isPullDown);
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ wineXRefreshView.stopRefresh();
+ }
+ }, 1000);
+ }
+ });
+ }
+
+}
diff --git a/app/src/main/java/com/andview/example/activity/BannerRecyclerViewActivity.java b/app/src/main/java/com/andview/example/activity/recyclerview/BannerRecyclerViewActivity.java
similarity index 74%
rename from app/src/main/java/com/andview/example/activity/BannerRecyclerViewActivity.java
rename to app/src/main/java/com/andview/example/activity/recyclerview/BannerRecyclerViewActivity.java
index 3e88410..f728ebc 100644
--- a/app/src/main/java/com/andview/example/activity/BannerRecyclerViewActivity.java
+++ b/app/src/main/java/com/andview/example/activity/recyclerview/BannerRecyclerViewActivity.java
@@ -1,10 +1,10 @@
-package com.andview.example.activity;
+package com.andview.example.activity.recyclerview;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
-import android.support.v7.widget.GridLayoutManager;
-import android.support.v7.widget.RecyclerView;
+import androidx.recyclerview.widget.GridLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
@@ -22,6 +22,7 @@
import java.util.ArrayList;
import java.util.List;
+import java.util.Random;
public class BannerRecyclerViewActivity extends Activity {
RecyclerView recyclerView;
@@ -50,7 +51,7 @@ protected void onCreate(Bundle savedInstanceState) {
initData();
adapter = new SimpleAdapter(personList, this);
// 设置静默加载模式
-// xRefreshView.setSilenceLoadMore();
+// xRefreshView1.setSilenceLoadMore();
layoutManager = new GridLayoutManager(this, 2);
recyclerView.setLayoutManager(layoutManager);
headerView = adapter.setHeaderView(R.layout.bannerview, recyclerView);
@@ -66,33 +67,45 @@ protected void onCreate(Bundle savedInstanceState) {
xRefreshView.setAutoLoadMore(false);
xRefreshView.setPinnedTime(1000);
xRefreshView.setMoveForHorizontal(true);
-// adapter.setHeaderView(headerView, recyclerView);
+ xRefreshView.setPullLoadEnable(true);
+// recyclerviewAdapter.setHeaderView(headerView, recyclerView);
adapter.setCustomLoadMoreView(new XRefreshViewFooter(this));
-// xRefreshView.setPullRefreshEnable(false);
+// xRefreshView1.setPullRefreshEnable(false);
//设置在下拉刷新被禁用的情况下,是否允许界面被下拉,默认是true
-// xRefreshView.setMoveHeadWhenDisablePullRefresh(false);
-// xRefreshView.enablePullUpWhenLoadCompleted(false);
-// xRefreshView.setPullLoadEnable(false);
-// xRefreshView.enableRecyclerViewPullUp(false);
+// xRefreshView1.setMoveHeadWhenDisablePullRefresh(false);
+// xRefreshView1.enablePullUpWhenLoadCompleted(false);
+// xRefreshView1.setPullLoadEnable(false);
+// xRefreshView1.enableRecyclerViewPullUp(false);
//设置静默加载时提前加载的item个数
-// xRefreshView.setPreLoadCount(2);
+// xRefreshView1.setPreLoadCount(2);
xRefreshView.setXRefreshViewListener(new SimpleXRefreshListener() {
@Override
- public void onRefresh() {
+ public void onRefresh(boolean isPullDown) {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
- xRefreshView.stopRefresh();
+ //模拟数据加载失败的情况
+ Random random = new Random();
+ boolean success = random.nextBoolean();
+ if (success) {
+ xRefreshView.stopRefresh();
+ } else {
+ xRefreshView.stopRefresh(false);
+ }
+ //或者
+// xRefreshView1.stopRefresh(success);
}
}, 2000);
}
@Override
- public void onLoadMore(boolean isSlience) {
+ public void onLoadMore(boolean isSilence) {
new Handler().postDelayed(new Runnable() {
public void run() {
+ if(xRefreshView.hasLoadCompleted()){
+ }
for (int i = 0; i < 6; i++) {
adapter.insert(new Person("More ", "21"),
adapter.getAdapterItemCount());
@@ -102,7 +115,7 @@ public void run() {
xRefreshView.setLoadComplete(true);
} else {
// 刷新完成必须调用此方法停止加载
- xRefreshView.stopLoadMore();
+ xRefreshView.stopLoadMore(false);
}
}
}, 1000);
@@ -111,7 +124,7 @@ public void run() {
}
private void initData() {
- for (int i = 0; i < 3; i++) {
+ for (int i = 0; i < 10; i++) {
Person person = new Person("name" + i, "" + i);
personList.add(person);
}
@@ -141,8 +154,8 @@ public boolean onOptionsItemSelected(MenuItem item) {
break;
case R.id.menu_refresh:
xRefreshView.startRefresh();
-// xRefreshView.setPullRefreshEnable(true);
-// xRefreshView.setPullLoadEnable(!xRefreshView.getPullLoadEnable());
+// xRefreshView1.setPullRefreshEnable(true);
+// xRefreshView1.setPullLoadEnable(!xRefreshView1.getPullLoadEnable());
break;
}
diff --git a/app/src/main/java/com/andview/example/activity/GridRecyclerViewActivity.java b/app/src/main/java/com/andview/example/activity/recyclerview/GridRecyclerViewActivity.java
similarity index 85%
rename from app/src/main/java/com/andview/example/activity/GridRecyclerViewActivity.java
rename to app/src/main/java/com/andview/example/activity/recyclerview/GridRecyclerViewActivity.java
index 042613f..820beec 100644
--- a/app/src/main/java/com/andview/example/activity/GridRecyclerViewActivity.java
+++ b/app/src/main/java/com/andview/example/activity/recyclerview/GridRecyclerViewActivity.java
@@ -1,10 +1,10 @@
-package com.andview.example.activity;
+package com.andview.example.activity.recyclerview;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
-import android.support.v7.widget.GridLayoutManager;
-import android.support.v7.widget.RecyclerView;
+import androidx.recyclerview.widget.GridLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
import android.view.Menu;
import android.view.MenuItem;
@@ -40,12 +40,12 @@ protected void onCreate(Bundle savedInstanceState) {
initData();
adapter = new SimpleAdapter(personList,this);
// 设置静默加载模式
-// xRefreshView.setSilenceLoadMore();
+// xRefreshView1.setSilenceLoadMore();
layoutManager = new GridLayoutManager(this,2);
recyclerView.setLayoutManager(layoutManager);
// 静默加载模式不能设置footerview
recyclerView.setAdapter(adapter);
-// xRefreshView.setAutoLoadMore(false);
+// xRefreshView1.setAutoLoadMore(false);
xRefreshView.setPinnedTime(1000);
xRefreshView.setMoveForHorizontal(true);
@@ -53,18 +53,18 @@ protected void onCreate(Bundle savedInstanceState) {
//并注释掉第四行代码
// CustomerFooter customerFooter = new CustomerFooter(this);
// customerFooter.setRecyclerView(recyclerView);
-// adapter.setCustomLoadMoreView(customerFooter);
+// recyclerviewAdapter.setCustomLoadMoreView(customerFooter);
adapter.setCustomLoadMoreView(new XRefreshViewFooter(this));
-// adapter.setCustomLoadMoreView(new XRefreshViewFooter(this));
-// xRefreshView.setPullLoadEnable(false);
+// recyclerviewAdapter.setCustomLoadMoreView(new XRefreshViewFooter(this));
+// xRefreshView1.setPullLoadEnable(false);
//设置静默加载时提前加载的item个数
-// xRefreshView.setPreLoadCount(2);
+// xRefreshView1.setPreLoadCount(2);
xRefreshView.setXRefreshViewListener(new SimpleXRefreshListener() {
@Override
- public void onRefresh() {
+ public void onRefresh(boolean isPullDown) {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
@@ -74,7 +74,7 @@ public void run() {
}
@Override
- public void onLoadMore(boolean isSlience) {
+ public void onLoadMore(boolean isSilence) {
new Handler().postDelayed(new Runnable() {
public void run() {
for (int i = 0; i < 6; i++) {
@@ -93,7 +93,7 @@ public void run() {
}
});
// // 实现Recyclerview的滚动监听,在这里可以自己处理到达底部加载更多的操作,可以不实现onLoadMore方法,更加自由
-// xRefreshView.setOnRecyclerViewScrollListener(new OnScrollListener() {
+// xRefreshView1.setOnRecyclerViewScrollListener(new OnScrollListener() {
// @Override
// public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
// super.onScrolled(recyclerView, dx, dy);
@@ -103,7 +103,7 @@ public void run() {
// public void onScrollStateChanged(RecyclerView recyclerView,
// int newState) {
// if (newState == RecyclerView.SCROLL_STATE_IDLE) {
-// isBottom = adapter.getItemCount() - 1 == lastVisibleItem;
+// isBottom = recyclerviewAdapter.getItemCount() - 1 == lastVisibleItem;
// }
// }
// });
diff --git a/app/src/main/java/com/andview/example/activity/LinearRecyclerViewActivity.java b/app/src/main/java/com/andview/example/activity/recyclerview/LinearRecyclerViewActivity.java
similarity index 75%
rename from app/src/main/java/com/andview/example/activity/LinearRecyclerViewActivity.java
rename to app/src/main/java/com/andview/example/activity/recyclerview/LinearRecyclerViewActivity.java
index c117281..a2046eb 100644
--- a/app/src/main/java/com/andview/example/activity/LinearRecyclerViewActivity.java
+++ b/app/src/main/java/com/andview/example/activity/recyclerview/LinearRecyclerViewActivity.java
@@ -1,11 +1,11 @@
-package com.andview.example.activity;
+package com.andview.example.activity.recyclerview;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
-import android.support.v7.widget.GridLayoutManager;
-import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
+import androidx.recyclerview.widget.GridLayoutManager;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
import android.view.Menu;
import android.view.MenuItem;
@@ -44,7 +44,7 @@ protected void onCreate(Bundle savedInstanceState) {
initData();
adapter = new SimpleAdapter(personList, this);
// 设置静默加载模式
-// xRefreshView.setSilenceLoadMore();
+// xRefreshView1.setSilenceLoadMore();
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
// 静默加载模式不能设置footerview
@@ -59,12 +59,23 @@ protected void onCreate(Bundle savedInstanceState) {
xRefreshView.enableRecyclerViewPullUp(true);
xRefreshView.enablePullUpWhenLoadCompleted(true);
//设置静默加载时提前加载的item个数
-// xRefreshView.setPreLoadCount(4);
+// xefreshView1.setPreLoadCount(4);
+ //设置Recyclerview的滑动监听
+ xRefreshView.setOnRecyclerViewScrollListener(new RecyclerView.OnScrollListener() {
+ @Override
+ public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
+ super.onScrollStateChanged(recyclerView, newState);
+ }
+ @Override
+ public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
+ super.onScrolled(recyclerView, dx, dy);
+ }
+ });
xRefreshView.setXRefreshViewListener(new SimpleXRefreshListener() {
@Override
- public void onRefresh() {
+ public void onRefresh(boolean isPullDown) {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
@@ -74,29 +85,29 @@ public void run() {
}
@Override
- public void onLoadMore(boolean isSlience) {
+ public void onLoadMore(boolean isSilence) {
new Handler().postDelayed(new Runnable() {
public void run() {
// for (int i = 0; i < 6; i++) {
-// adapter.insert(new Person("More ", mLoadCount + "21"),
-// adapter.getAdapterItemCount());
+// recyclerviewAdapter.insert(new Person("More ", mLoadCount + "21"),
+// recyclerviewAdapter.getAdapterItemCount());
// }
mLoadCount++;
- if (mLoadCount >= 3) {
+ if (mLoadCount >= 3) {//模拟没有更多数据的情况
xRefreshView.setLoadComplete(true);
} else {
// 刷新完成必须调用此方法停止加载
- xRefreshView.stopLoadMore();
- //当数据加载失败时,可以调用以下方法,传入false,不传默认为true
+ xRefreshView.stopLoadMore(false);
+ //当数据加载失败 不需要隐藏footerview时,可以调用以下方法,传入false,不传默认为true
// 同时在Footerview的onStateFinish(boolean hideFooter),可以在hideFooter为false时,显示数据加载失败的ui
-// xRefreshView.stopLoadMore(false);
+// xRefreshView1.stopLoadMore(false);
}
}
}, 1000);
}
});
// // 实现Recyclerview的滚动监听,在这里可以自己处理到达底部加载更多的操作,可以不实现onLoadMore方法,更加自由
-// xRefreshView.setOnRecyclerViewScrollListener(new OnScrollListener() {
+// xRefreshView1.setOnRecyclerViewScrollListener(new OnScrollListener() {
// @Override
// public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
// super.onScrolled(recyclerView, dx, dy);
@@ -106,14 +117,14 @@ public void run() {
// public void onScrollStateChanged(RecyclerView recyclerView,
// int newState) {
// if (newState == RecyclerView.SCROLL_STATE_IDLE) {
-// isBottom = adapter.getItemCount() - 1 == lastVisibleItem;
+// isBottom = recyclerviewAdapter.getItemCount() - 1 == lastVisibleItem;
// }
// }
// });
}
private void initData() {
- for (int i = 0; i < 30; i++) {
+ for (int i = 0; i < 15; i++) {
Person person = new Person("name" + i, "" + i);
personList.add(person);
}
diff --git a/app/src/main/java/com/andview/example/activity/MultiItemRecyclerViewActivity.java b/app/src/main/java/com/andview/example/activity/recyclerview/MultiItemRecyclerViewActivity.java
similarity index 87%
rename from app/src/main/java/com/andview/example/activity/MultiItemRecyclerViewActivity.java
rename to app/src/main/java/com/andview/example/activity/recyclerview/MultiItemRecyclerViewActivity.java
index 5d186b8..0917b64 100644
--- a/app/src/main/java/com/andview/example/activity/MultiItemRecyclerViewActivity.java
+++ b/app/src/main/java/com/andview/example/activity/recyclerview/MultiItemRecyclerViewActivity.java
@@ -1,10 +1,10 @@
-package com.andview.example.activity;
+package com.andview.example.activity.recyclerview;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
-import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
import android.view.Menu;
import android.view.MenuItem;
@@ -39,7 +39,7 @@ protected void onCreate(Bundle savedInstanceState) {
adapter = new MultiItemAdapter(personList);
// 设置静默加载模式
-// xRefreshView.setSilenceLoadMore();
+// xRefreshView1.setSilenceLoadMore();
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
// 静默加载模式不能设置footerview
@@ -48,15 +48,15 @@ protected void onCreate(Bundle savedInstanceState) {
xRefreshView.setPinnedTime(1000);
xRefreshView.setPullLoadEnable(true);
xRefreshView.setMoveForHorizontal(true);
-// xRefreshView.setAutoLoadMore(true);
+// xRefreshView1.setAutoLoadMore(true);
adapter.setCustomLoadMoreView(new XRefreshViewFooter(this));
//设置静默加载时提前加载的item个数
-// xRefreshView.setPreLoadCount(4);
+// xRefreshView1.setPreLoadCount(4);
xRefreshView.setXRefreshViewListener(new SimpleXRefreshListener() {
@Override
- public void onRefresh() {
+ public void onRefresh(boolean isPullDown) {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
@@ -65,13 +65,12 @@ public void run() {
adapter.insert(new Person("More ", mLoadCount + "21", getType()),
adapter.getAdapterItemCount());
}
- xRefreshView.setLoadComplete(false);
}
}, 500);
}
@Override
- public void onLoadMore(boolean isSlience) {
+ public void onLoadMore(boolean isSilence) {
new Handler().postDelayed(new Runnable() {
public void run() {
for (int i = 0; i < 1; i++) {
@@ -84,13 +83,15 @@ public void run() {
} else {
// 刷新完成必须调用此方法停止加载
xRefreshView.stopLoadMore();
+ //如果数据加载完成以后不隐藏footerview,传入false
+// xRefreshView1.stopLoadMore(false);
}
}
}, 1000);
}
});
//如果想在数据加载完成以后不隐藏footerview则需要调用下面这行代码并传入false
-// xRefreshView.setHideFooterWhenComplete(false);
+// xRefreshView1.setHideFooterWhenComplete(false);
requestData();
}
diff --git a/app/src/main/java/com/andview/example/activity/recyclerview/ShowFooterWhenNoMoreDataRecyclerViewActivity.java b/app/src/main/java/com/andview/example/activity/recyclerview/ShowFooterWhenNoMoreDataRecyclerViewActivity.java
new file mode 100644
index 0000000..89e0af2
--- /dev/null
+++ b/app/src/main/java/com/andview/example/activity/recyclerview/ShowFooterWhenNoMoreDataRecyclerViewActivity.java
@@ -0,0 +1,172 @@
+package com.andview.example.activity.recyclerview;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.Handler;
+import androidx.recyclerview.widget.GridLayoutManager;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+import android.view.Menu;
+import android.view.MenuItem;
+
+import com.andview.example.R;
+import com.andview.example.recylerview.Person;
+import com.andview.example.recylerview.SimpleAdapter;
+import com.andview.example.ui.NoMoreDataFooterView;
+import com.andview.refreshview.XRefreshView;
+import com.andview.refreshview.XRefreshView.SimpleXRefreshListener;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ShowFooterWhenNoMoreDataRecyclerViewActivity extends Activity {
+ RecyclerView recyclerView;
+ SimpleAdapter adapter;
+ List personList = new ArrayList();
+ XRefreshView xRefreshView;
+ int lastVisibleItem = 0;
+ // GridLayoutManager layoutManager;
+ LinearLayoutManager layoutManager;
+ private boolean isBottom = false;
+ private int mLoadCount = 0;
+
+
+ private boolean isList = true;//false 为grid布局
+ private boolean noMoreData = false;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_recylerview2);
+ xRefreshView = (XRefreshView) findViewById(R.id.xrefreshview);
+ recyclerView = (RecyclerView) findViewById(R.id.recycler_view_test_rv);
+ recyclerView.setHasFixedSize(true);
+
+ initData();
+ adapter = new SimpleAdapter(personList, this);
+ // 设置静默加载模式
+// xRefreshView1.setSilenceLoadMore();
+ layoutManager = new LinearLayoutManager(this);
+ recyclerView.setLayoutManager(layoutManager);
+ // 静默加载模式不能设置footerview
+ recyclerView.setAdapter(adapter);
+ //设置刷新完成以后,headerview固定的时间
+ xRefreshView.setPinnedTime(1000);
+ xRefreshView.setMoveForHorizontal(true);
+ xRefreshView.setPullLoadEnable(true);
+ xRefreshView.setAutoLoadMore(true);
+ adapter.setCustomLoadMoreView(new NoMoreDataFooterView(this));
+ xRefreshView.enableReleaseToLoadMore(false);
+ xRefreshView.enableRecyclerViewPullUp(true);
+ xRefreshView.enablePullUpWhenLoadCompleted(true);
+ //设置静默加载时提前加载的item个数
+// xefreshView1.setPreLoadCount(4);
+ //设置Recyclerview的滑动监听
+ xRefreshView.setOnRecyclerViewScrollListener(new RecyclerView.OnScrollListener() {
+ @Override
+ public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
+ super.onScrollStateChanged(recyclerView, newState);
+ }
+
+ @Override
+ public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
+ super.onScrolled(recyclerView, dx, dy);
+ }
+ });
+ xRefreshView.setXRefreshViewListener(new SimpleXRefreshListener() {
+
+ @Override
+ public void onRefresh(boolean isPullDown) {
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ xRefreshView.stopRefresh();
+ }
+ }, 500);
+ }
+
+ @Override
+ public void onLoadMore(boolean isSilence) {
+ if (noMoreData) {
+ xRefreshView.stopLoadMore(false);
+ return;
+ }
+ new Handler().postDelayed(new Runnable() {
+ public void run() {
+ mLoadCount++;
+ if (mLoadCount >= 2) {//模拟没有更多数据的情况
+ xRefreshView.stopLoadMore(false);
+ noMoreData = true;
+ } else {
+ for (int i = 0; i < 6; i++) {
+ adapter.insert(new Person("More ", mLoadCount + "21"), adapter.getAdapterItemCount());
+ }
+ // 刷新完成必须调用此方法停止加载
+ xRefreshView.stopLoadMore();
+ //当数据加载失败 不需要隐藏footerview时,可以调用以下方法,传入false,不传默认为true
+ // 同时在Footerview的onStateFinish(boolean hideFooter),可以在hideFooter为false时,显示数据加载失败的ui
+// xRefreshView1.stopLoadMore(false);
+ }
+ }
+ }, 1000);
+ }
+ });
+// // 实现Recyclerview的滚动监听,在这里可以自己处理到达底部加载更多的操作,可以不实现onLoadMore方法,更加自由
+// xRefreshView1.setOnRecyclerViewScrollListener(new OnScrollListener() {
+// @Override
+// public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
+// super.onScrolled(recyclerView, dx, dy);
+// lastVisibleItem = layoutManager.findLastVisibleItemPosition();
+// }
+//
+// public void onScrollStateChanged(RecyclerView recyclerView,
+// int newState) {
+// if (newState == RecyclerView.SCROLL_STATE_IDLE) {
+// isBottom = recyclerviewAdapter.getItemCount() - 1 == lastVisibleItem;
+// }
+// }
+// });
+ }
+
+ private void initData() {
+ for (int i = 0; i < 15; i++) {
+ Person person = new Person("name" + i, "" + i);
+ personList.add(person);
+ }
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ // 加载菜单
+ getMenuInflater().inflate(R.menu.main, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ int menuId = item.getItemId();
+ switch (menuId) {
+ case R.id.menu_clear:
+ mLoadCount = 0;
+ noMoreData = false;
+ xRefreshView.setLoadComplete(false);
+ //切换布局
+ isList = !isList;
+
+ if (isList) {
+ LinearLayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
+ layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
+ recyclerView.setLayoutManager(layoutManager);
+ } else {
+ recyclerView.setLayoutManager(new GridLayoutManager(getApplicationContext(), 2));
+ }
+ //当切换layoutManager时,需调用此方法
+ xRefreshView.notifyLayoutManagerChanged();
+ break;
+ case R.id.menu_refresh:
+ xRefreshView.startRefresh();
+ break;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/andview/example/activity/SilenceRecyclerViewActivity.java b/app/src/main/java/com/andview/example/activity/recyclerview/SilenceRecyclerViewActivity.java
similarity index 87%
rename from app/src/main/java/com/andview/example/activity/SilenceRecyclerViewActivity.java
rename to app/src/main/java/com/andview/example/activity/recyclerview/SilenceRecyclerViewActivity.java
index 7ea2223..0962c95 100644
--- a/app/src/main/java/com/andview/example/activity/SilenceRecyclerViewActivity.java
+++ b/app/src/main/java/com/andview/example/activity/recyclerview/SilenceRecyclerViewActivity.java
@@ -1,14 +1,15 @@
-package com.andview.example.activity;
+package com.andview.example.activity.recyclerview;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
-import android.support.v7.widget.GridLayoutManager;
-import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
import android.view.Menu;
import android.view.MenuItem;
+import androidx.recyclerview.widget.GridLayoutManager;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
import com.andview.example.R;
import com.andview.example.recylerview.Person;
import com.andview.example.recylerview.SimpleAdapter;
@@ -47,24 +48,24 @@ protected void onCreate(Bundle savedInstanceState) {
initData();
adapter = new SimpleAdapter(personList, this);
// 设置静默加载模式
- xRefreshView.setSilenceLoadMore();
+ xRefreshView.setSilenceLoadMore(true);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
// 静默加载模式不能设置footerview
recyclerView.setAdapter(adapter);
-// xRefreshView.setAutoLoadMore(true);
+// xRefreshView1.setAutoLoadMore(true);
//设置刷新完成以后,headerview固定的时间
xRefreshView.setPinnedTime(1000);
xRefreshView.setMoveForHorizontal(true);
-// adapter.setCustomLoadMoreView(new XRefreshViewFooter(this));
-// xRefreshView.setPullLoadEnable(false);
+// recyclerviewAdapter.setCustomLoadMoreView(new XRefreshViewFooter(this));
+// xRefreshView1.setPullLoadEnable(false);
//设置静默加载时提前加载的item个数
xRefreshView.setPreLoadCount(4);
xRefreshView.setXRefreshViewListener(new SimpleXRefreshListener() {
@Override
- public void onRefresh() {
+ public void onRefresh(boolean isPullDown) {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
@@ -74,7 +75,7 @@ public void run() {
}
@Override
- public void onLoadMore(boolean isSlience) {
+ public void onLoadMore(boolean isSilence) {
new Handler().postDelayed(new Runnable() {
public void run() {
for (int i = 0; i < 6; i++) {
@@ -94,7 +95,7 @@ public void run() {
}
});
// // 实现Recyclerview的滚动监听,在这里可以自己处理到达底部加载更多的操作,可以不实现onLoadMore方法,更加自由
-// xRefreshView.setOnRecyclerViewScrollListener(new OnScrollListener() {
+// xRefreshView1.setOnRecyclerViewScrollListener(new OnScrollListener() {
// @Override
// public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
// super.onScrolled(recyclerView, dx, dy);
@@ -104,7 +105,7 @@ public void run() {
// public void onScrollStateChanged(RecyclerView recyclerView,
// int newState) {
// if (newState == RecyclerView.SCROLL_STATE_IDLE) {
-// isBottom = adapter.getItemCount() - 1 == lastVisibleItem;
+// isBottom = recyclerviewAdapter.getItemCount() - 1 == lastVisibleItem;
// }
// }
// });
diff --git a/app/src/main/java/com/andview/example/activity/StaggeredRecyclerViewActivity.java b/app/src/main/java/com/andview/example/activity/recyclerview/StaggeredRecyclerViewActivity.java
similarity index 87%
rename from app/src/main/java/com/andview/example/activity/StaggeredRecyclerViewActivity.java
rename to app/src/main/java/com/andview/example/activity/recyclerview/StaggeredRecyclerViewActivity.java
index ef5adab..e2e2020 100644
--- a/app/src/main/java/com/andview/example/activity/StaggeredRecyclerViewActivity.java
+++ b/app/src/main/java/com/andview/example/activity/recyclerview/StaggeredRecyclerViewActivity.java
@@ -1,13 +1,14 @@
-package com.andview.example.activity;
+package com.andview.example.activity.recyclerview;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.Menu;
import android.view.MenuItem;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.recyclerview.widget.StaggeredGridLayoutManager;
+
import com.andview.example.R;
import com.andview.example.recylerview.Person;
import com.andview.example.recylerview.SimpleAdapter;
@@ -40,23 +41,23 @@ protected void onCreate(Bundle savedInstanceState) {
initData();
adapter = new SimpleAdapter(personList,this);
// 设置静默加载模式
-// xRefreshView.setSilenceLoadMore();
+// xRefreshView1.setSilenceLoadMore();
layoutManager = new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
// 静默加载模式不能设置footerview
recyclerView.setAdapter(adapter);
-// xRefreshView.setAutoLoadMore(true);
+// xRefreshView1.setAutoLoadMore(true);
xRefreshView.setPinnedTime(1000);
xRefreshView.setMoveForHorizontal(true);
adapter.setCustomLoadMoreView(new XRefreshViewFooter(this));
-// xRefreshView.setPullLoadEnable(false);
+// xRefreshView1.setPullLoadEnable(false);
//设置静默加载时提前加载的item个数
-// xRefreshView.setPreLoadCount(2);
+// xRefreshView1.setPreLoadCount(2);
xRefreshView.setXRefreshViewListener(new SimpleXRefreshListener() {
@Override
- public void onRefresh() {
+ public void onRefresh(boolean isPullDown) {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
@@ -66,7 +67,7 @@ public void run() {
}
@Override
- public void onLoadMore(boolean isSlience) {
+ public void onLoadMore(boolean isSilence) {
new Handler().postDelayed(new Runnable() {
public void run() {
for (int i = 0; i < 6; i++) {
@@ -85,7 +86,7 @@ public void run() {
}
});
// // 实现Recyclerview的滚动监听,在这里可以自己处理到达底部加载更多的操作,可以不实现onLoadMore方法,更加自由
-// xRefreshView.setOnRecyclerViewScrollListener(new OnScrollListener() {
+// xRefreshView1.setOnRecyclerViewScrollListener(new OnScrollListener() {
// @Override
// public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
// super.onScrolled(recyclerView, dx, dy);
@@ -95,7 +96,7 @@ public void run() {
// public void onScrollStateChanged(RecyclerView recyclerView,
// int newState) {
// if (newState == RecyclerView.SCROLL_STATE_IDLE) {
-// isBottom = adapter.getItemCount() - 1 == lastVisibleItem;
+// isBottom = recyclerviewAdapter.getItemCount() - 1 == lastVisibleItem;
// }
// }
// });
diff --git a/app/src/main/java/com/andview/example/activity/recyclerview/WithoutBaseAdapterRecyclerViewActivity.java b/app/src/main/java/com/andview/example/activity/recyclerview/WithoutBaseAdapterRecyclerViewActivity.java
new file mode 100644
index 0000000..b1673f7
--- /dev/null
+++ b/app/src/main/java/com/andview/example/activity/recyclerview/WithoutBaseAdapterRecyclerViewActivity.java
@@ -0,0 +1,169 @@
+package com.andview.example.activity.recyclerview;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.Handler;
+import androidx.recyclerview.widget.GridLayoutManager;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+import android.view.Menu;
+import android.view.MenuItem;
+
+import com.andview.example.R;
+import com.andview.example.recylerview.Person;
+import com.andview.example.recylerview.NormalRecyclerAdapter;
+import com.andview.refreshview.XRefreshView;
+import com.andview.refreshview.XRefreshView.SimpleXRefreshListener;
+import com.andview.refreshview.utils.LogUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class WithoutBaseAdapterRecyclerViewActivity extends Activity {
+ RecyclerView recyclerView;
+ NormalRecyclerAdapter adapter;
+ List personList = new ArrayList();
+ XRefreshView xRefreshView;
+ int lastVisibleItem = 0;
+ // GridLayoutManager layoutManager;
+ LinearLayoutManager layoutManager;
+ private boolean isBottom = false;
+ private int mLoadCount = 0;
+
+
+ private boolean isList = true;//false 为grid布局
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_recylerview2);
+ xRefreshView = (XRefreshView) findViewById(R.id.xrefreshview);
+ recyclerView = (RecyclerView) findViewById(R.id.recycler_view_test_rv);
+ recyclerView.setHasFixedSize(true);
+
+ initData();
+ adapter = new NormalRecyclerAdapter(personList, this);
+ // 设置静默加载模式
+// xRefreshView1.setSilenceLoadMore();
+ layoutManager = new LinearLayoutManager(this);
+ recyclerView.setLayoutManager(layoutManager);
+ // 静默加载模式不能设置footerview
+ recyclerView.setAdapter(adapter);
+ //设置刷新完成以后,headerview固定的时间
+ xRefreshView.setPinnedTime(1000);
+ xRefreshView.setMoveForHorizontal(true);
+ xRefreshView.setPullLoadEnable(true);
+ xRefreshView.setAutoLoadMore(false);
+// adapter.setCustomLoadMoreView(new XRefreshViewFooter(this));
+ xRefreshView.enableReleaseToLoadMore(true);
+ xRefreshView.enableRecyclerViewPullUp(true);
+ xRefreshView.enablePullUpWhenLoadCompleted(true);
+ //设置静默加载时提前加载的item个数
+// xRefreshView1.setPreLoadCount(4);
+ //设置Recyclerview的滑动监听
+ xRefreshView.setOnRecyclerViewScrollListener(new RecyclerView.OnScrollListener() {
+ @Override
+ public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
+ super.onScrollStateChanged(recyclerView, newState);
+ LogUtils.e("onScrollStateChanged");
+ }
+
+ @Override
+ public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
+ super.onScrolled(recyclerView, dx, dy);
+ LogUtils.e("onScrolled");
+ }
+ });
+
+ xRefreshView.setXRefreshViewListener(new SimpleXRefreshListener() {
+
+ @Override
+ public void onRefresh(boolean isPullDown) {
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ xRefreshView.stopRefresh();
+ }
+ }, 500);
+ }
+
+ @Override
+ public void onLoadMore(boolean isSilence) {
+ new Handler().postDelayed(new Runnable() {
+ public void run() {
+// for (int i = 0; i < 6; i++) {
+// recyclerviewAdapter.insert(new Person("More ", mLoadCount + "21"),
+// recyclerviewAdapter.getAdapterItemCount());
+// }
+ mLoadCount++;
+ if (mLoadCount >= 3) {//模拟没有更多数据的情况
+ xRefreshView.setLoadComplete(true);
+ } else {
+ // 刷新完成必须调用此方法停止加载
+ xRefreshView.stopLoadMore(false);
+ //当数据加载失败 不需要隐藏footerview时,可以调用以下方法,传入false,不传默认为true
+ // 同时在Footerview的onStateFinish(boolean hideFooter),可以在hideFooter为false时,显示数据加载失败的ui
+// xRefreshView1.stopLoadMore(false);
+ }
+ }
+ }, 1000);
+ }
+ });
+// // 实现Recyclerview的滚动监听,在这里可以自己处理到达底部加载更多的操作,可以不实现onLoadMore方法,更加自由
+// xRefreshView1.setOnRecyclerViewScrollListener(new OnScrollListener() {
+// @Override
+// public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
+// super.onScrolled(recyclerView, dx, dy);
+// lastVisibleItem = layoutManager.findLastVisibleItemPosition();
+// }
+//
+// public void onScrollStateChanged(RecyclerView recyclerView,
+// int newState) {
+// if (newState == RecyclerView.SCROLL_STATE_IDLE) {
+// isBottom = recyclerviewAdapter.getItemCount() - 1 == lastVisibleItem;
+// }
+// }
+// });
+ }
+
+ private void initData() {
+ for (int i = 0; i < 30; i++) {
+ Person person = new Person("name" + i, "" + i);
+ personList.add(person);
+ }
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ // 加载菜单
+ getMenuInflater().inflate(R.menu.main, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ int menuId = item.getItemId();
+ switch (menuId) {
+ case R.id.menu_clear:
+ mLoadCount = 0;
+ xRefreshView.setLoadComplete(false);
+ //切换布局
+ isList = !isList;
+
+ if (isList) {
+ LinearLayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
+ layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
+ recyclerView.setLayoutManager(layoutManager);
+ } else {
+ recyclerView.setLayoutManager(new GridLayoutManager(getApplicationContext(), 2));
+ }
+ //当切换layoutManager时,需调用此方法,如果Recyclerview的adapter没有集成BaseRecyclerAdapter,则不用加这行代码
+// xRefreshView.notifyLayoutManagerChanged();
+ break;
+ case R.id.menu_refresh:
+ xRefreshView.startRefresh();
+ break;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/andview/example/recylerview/MultiItemAdapter.java b/app/src/main/java/com/andview/example/recylerview/MultiItemAdapter.java
index e9b2c5d..a78d626 100644
--- a/app/src/main/java/com/andview/example/recylerview/MultiItemAdapter.java
+++ b/app/src/main/java/com/andview/example/recylerview/MultiItemAdapter.java
@@ -1,6 +1,6 @@
package com.andview.example.recylerview;
-import android.support.v7.widget.RecyclerView;
+import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -21,7 +21,12 @@ public MultiItemAdapter(List list) {
@Override
public void onBindViewHolder(SimpleAdapterViewHolder holder, int position, boolean isItem) {
Person person = list.get(position);
- holder.nameTv.setText(person.getName());
+ int type = getAdapterItemViewType(position);
+ if (type == 0) {
+ holder.tvLeft.setText(person.getName());
+ } else {
+ holder.tvRight.setText(person.getName());
+ }
}
@Override
@@ -62,7 +67,7 @@ public SimpleAdapterViewHolder onCreateViewHolder(ViewGroup parent, int viewType
public class SimpleAdapterViewHolder extends RecyclerView.ViewHolder {
- public TextView nameTv;
+ public TextView tvRight, tvLeft;
public SimpleAdapterViewHolder(View itemView, boolean isItem) {
super(itemView);
@@ -78,10 +83,10 @@ private void init(View itemView, int viewType, boolean isItem) {
if (isItem) {
switch (viewType) {
case 0:
- nameTv = (TextView) itemView.findViewById(R.id.tv_multi_left);
+ tvLeft = (TextView) itemView.findViewById(R.id.tv_multi_left);
break;
default:
- nameTv = (TextView) itemView.findViewById(R.id.tv_multi_right);
+ tvRight = (TextView) itemView.findViewById(R.id.tv_multi_right);
break;
}
}
diff --git a/app/src/main/java/com/andview/example/recylerview/NormalRecyclerAdapter.java b/app/src/main/java/com/andview/example/recylerview/NormalRecyclerAdapter.java
new file mode 100644
index 0000000..4ce99da
--- /dev/null
+++ b/app/src/main/java/com/andview/example/recylerview/NormalRecyclerAdapter.java
@@ -0,0 +1,88 @@
+package com.andview.example.recylerview;
+
+import android.content.Context;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.recyclerview.widget.StaggeredGridLayoutManager;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import com.andview.example.DensityUtil;
+import com.andview.example.R;
+
+import java.util.List;
+
+public class NormalRecyclerAdapter extends RecyclerView.Adapter {
+ private List list;
+ private int largeCardHeight, smallCardHeight;
+
+ public NormalRecyclerAdapter(List list, Context context) {
+ this.list = list;
+ largeCardHeight = DensityUtil.dip2px(context, 150);
+ smallCardHeight = DensityUtil.dip2px(context, 100);
+ }
+
+ @Override
+ public void onBindViewHolder(SimpleAdapterViewHolder holder, int position) {
+ Person person = list.get(position);
+ holder.nameTv.setText(person.getName());
+ holder.ageTv.setText(person.getAge());
+ ViewGroup.LayoutParams layoutParams = holder.itemView.getLayoutParams();
+ if (layoutParams instanceof StaggeredGridLayoutManager.LayoutParams) {
+ holder.rootView.getLayoutParams().height = position % 2 != 0 ? largeCardHeight : smallCardHeight;
+ }
+ }
+
+ @Override
+ public int getItemCount() {
+ return list.size();
+ }
+
+ public void setData(List list) {
+ this.list = list;
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public SimpleAdapterViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ View v = LayoutInflater.from(parent.getContext()).inflate(
+ R.layout.item_recylerview, parent, false);
+ SimpleAdapterViewHolder vh = new SimpleAdapterViewHolder(v, true);
+ return vh;
+ }
+
+ public void insert(Person person, int position) {
+ list.add(position, person);
+ notifyItemInserted(position);
+ }
+
+ public class SimpleAdapterViewHolder extends RecyclerView.ViewHolder {
+
+ public View rootView;
+ public TextView nameTv;
+ public TextView ageTv;
+ public int position;
+
+ public SimpleAdapterViewHolder(View itemView, boolean isItem) {
+ super(itemView);
+ if (isItem) {
+ nameTv = (TextView) itemView
+ .findViewById(R.id.recycler_view_test_item_person_name_tv);
+ ageTv = (TextView) itemView
+ .findViewById(R.id.recycler_view_test_item_person_age_tv);
+ rootView = itemView
+ .findViewById(R.id.card_view);
+ }
+
+ }
+ }
+
+ public Person getItem(int position) {
+ if (position < list.size())
+ return list.get(position);
+ else
+ return null;
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/andview/example/recylerview/SimpleAdapter.java b/app/src/main/java/com/andview/example/recylerview/SimpleAdapter.java
index a4138de..66e2a9b 100644
--- a/app/src/main/java/com/andview/example/recylerview/SimpleAdapter.java
+++ b/app/src/main/java/com/andview/example/recylerview/SimpleAdapter.java
@@ -1,13 +1,14 @@
package com.andview.example.recylerview;
import android.content.Context;
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.recyclerview.widget.StaggeredGridLayoutManager;
+
import com.andview.example.DensityUtil;
import com.andview.example.R;
import com.andview.refreshview.recyclerview.BaseRecyclerAdapter;
diff --git a/app/src/main/java/com/andview/example/ui/AdHeader.java b/app/src/main/java/com/andview/example/ui/AdHeader.java
index fab1318..0dea346 100644
--- a/app/src/main/java/com/andview/example/ui/AdHeader.java
+++ b/app/src/main/java/com/andview/example/ui/AdHeader.java
@@ -67,7 +67,7 @@ private void initView(Context context) {
mRotateDownAnim = new RotateAnimation(-180.0f, 0.0f,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
- mRotateDownAnim.setDuration(ROTATE_ANIM_DURATION);
+ mRotateDownAnim.setDuration(0);
mRotateDownAnim.setFillAfter(true);
}
@@ -139,7 +139,7 @@ public void onStateRefreshing() {
}
@Override
- public void onStateFinish() {
+ public void onStateFinish(boolean success) {
mArrowImageView.setVisibility(View.GONE);
mOkImageView.setVisibility(View.VISIBLE);
mProgressBar.setVisibility(View.GONE);
diff --git a/app/src/main/java/com/andview/example/ui/BannerViewPager.java b/app/src/main/java/com/andview/example/ui/BannerViewPager.java
index 0eb9350..c4edec2 100644
--- a/app/src/main/java/com/andview/example/ui/BannerViewPager.java
+++ b/app/src/main/java/com/andview/example/ui/BannerViewPager.java
@@ -1,11 +1,12 @@
package com.andview.example.ui;
import android.content.Context;
-import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ViewGroup;
+import androidx.viewpager.widget.ViewPager;
+
/**
* Created by huxq17 on 2016/2/1.
*/
diff --git a/app/src/main/java/com/andview/example/ui/CustomFooterView.java b/app/src/main/java/com/andview/example/ui/CustomFooterView.java
new file mode 100644
index 0000000..20736fd
--- /dev/null
+++ b/app/src/main/java/com/andview/example/ui/CustomFooterView.java
@@ -0,0 +1,136 @@
+package com.andview.example.ui;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.andview.refreshview.XRefreshView;
+import com.andview.refreshview.callback.IFooterCallBack;
+import com.andview.refreshview.utils.Utils;
+
+public class CustomFooterView extends LinearLayout implements IFooterCallBack {
+ private Context mContext;
+
+ private View mContentView;
+ private View mProgressBar;
+ private TextView mHintView;
+ private TextView mClickView;
+ private boolean showing = true;
+
+ public CustomFooterView(Context context) {
+ super(context);
+ initView(context);
+ }
+
+ public CustomFooterView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ initView(context);
+ }
+
+ @Override
+ public void callWhenNotAutoLoadMore(final XRefreshView xRefreshView) {
+ View childView = xRefreshView.getChildAt(1);
+ if (childView != null && childView instanceof RecyclerView) {
+ show(Utils.isRecyclerViewFullscreen((RecyclerView) childView));
+ xRefreshView.enableReleaseToLoadMore(Utils.isRecyclerViewFullscreen((RecyclerView) childView));
+ }
+ mClickView.setText(com.andview.refreshview.R.string.xrefreshview_footer_hint_click);
+ mClickView.setOnClickListener(new OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ xRefreshView.notifyLoadMore();
+ }
+ });
+ }
+
+ @Override
+ public void onStateReady() {
+ mHintView.setVisibility(View.GONE);
+ mProgressBar.setVisibility(View.GONE);
+ mClickView.setText(com.andview.refreshview.R.string.xrefreshview_footer_hint_click);
+ mClickView.setVisibility(View.VISIBLE);
+// show(true);
+ }
+
+ @Override
+ public void onStateRefreshing() {
+ mHintView.setVisibility(View.GONE);
+ mProgressBar.setVisibility(View.VISIBLE);
+ mClickView.setVisibility(View.GONE);
+ show(true);
+ }
+
+ @Override
+ public void onReleaseToLoadMore() {
+ mHintView.setVisibility(View.GONE);
+ mProgressBar.setVisibility(View.GONE);
+ mClickView.setText(com.andview.refreshview.R.string.xrefreshview_footer_hint_release);
+ mClickView.setVisibility(View.VISIBLE);
+ }
+
+ @Override
+ public void onStateFinish(boolean hideFooter) {
+ if (hideFooter) {
+ mHintView.setText(com.andview.refreshview.R.string.xrefreshview_footer_hint_normal);
+ } else {
+ //处理数据加载失败时ui显示的逻辑,也可以不处理,看自己的需求
+ mHintView.setText(com.andview.refreshview.R.string.xrefreshview_footer_hint_fail);
+ }
+ mHintView.setVisibility(View.VISIBLE);
+ mProgressBar.setVisibility(View.GONE);
+ mClickView.setVisibility(View.GONE);
+ }
+
+ @Override
+ public void onStateComplete() {
+ mHintView.setText(com.andview.refreshview.R.string.xrefreshview_footer_hint_complete);
+ mHintView.setVisibility(View.VISIBLE);
+ mProgressBar.setVisibility(View.GONE);
+ mClickView.setVisibility(View.GONE);
+ }
+
+ @Override
+ public void show(final boolean show) {
+ if (show == showing) {
+ return;
+ }
+ showing = show;
+ LayoutParams lp = (LayoutParams) mContentView
+ .getLayoutParams();
+ lp.height = show ? LayoutParams.WRAP_CONTENT : 0;
+ mContentView.setLayoutParams(lp);
+// setVisibility(show?VISIBLE:GONE);
+
+ }
+
+ @Override
+ public boolean isShowing() {
+ return showing;
+ }
+
+ private void initView(Context context) {
+ mContext = context;
+ ViewGroup moreView = (ViewGroup) LayoutInflater.from(mContext).inflate(com.andview.refreshview.R.layout.xrefreshview_footer, this);
+ moreView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
+
+ mContentView = moreView.findViewById(com.andview.refreshview.R.id.xrefreshview_footer_content);
+ mProgressBar = moreView
+ .findViewById(com.andview.refreshview.R.id.xrefreshview_footer_progressbar);
+ mHintView = (TextView) moreView
+ .findViewById(com.andview.refreshview.R.id.xrefreshview_footer_hint_textview);
+ mClickView = (TextView) moreView
+ .findViewById(com.andview.refreshview.R.id.xrefreshview_footer_click_textview);
+ }
+
+ @Override
+ public int getFooterHeight() {
+ return getMeasuredHeight();
+ }
+}
diff --git a/app/src/main/java/com/andview/example/ui/CustomGifHeader.java b/app/src/main/java/com/andview/example/ui/CustomGifHeader.java
index 80b4591..e33e1b6 100644
--- a/app/src/main/java/com/andview/example/ui/CustomGifHeader.java
+++ b/app/src/main/java/com/andview/example/ui/CustomGifHeader.java
@@ -44,9 +44,6 @@ private void initView(Context context) {
public void setRefreshTime(long lastRefreshTime) {
}
- /**
- * hide footer when disable pull load more
- */
public void hide() {
setVisibility(View.GONE);
}
@@ -79,15 +76,15 @@ public void onStateRefreshing() {
}
@Override
- public void onStateFinish() {
- mHintTextView.setText(R.string.xrefreshview_header_hint_loaded);
+ public void onStateFinish(boolean success) {
+ mHintTextView.setText(success ? R.string.xrefreshview_header_hint_loaded : R.string.xrefreshview_header_hint_loaded_fail);
// gifView1.setVisibility(View.VISIBLE);
gifView2.setVisibility(View.GONE);
gifView2.setPaused(true);
}
@Override
- public void onHeaderMove(double offset, int offsetY, int deltaY) {
+ public void onHeaderMove(double headerMovePercent, int offsetY, int deltaY) {
//
}
diff --git a/app/src/main/java/com/andview/example/ui/CustomHeader.java b/app/src/main/java/com/andview/example/ui/CustomHeader.java
index 2282f5e..cc2157a 100644
--- a/app/src/main/java/com/andview/example/ui/CustomHeader.java
+++ b/app/src/main/java/com/andview/example/ui/CustomHeader.java
@@ -19,10 +19,12 @@ public class CustomHeader extends View implements IHeaderCallBack {
, 0xFF00FFFF, 0xFFFF0000, 0xFF8B00FF, 0xFFFFFF00};
// Default background for the progress spinner
private static final int CIRCLE_BG_LIGHT = 0xFFFAFAFA;
+ private int mPinnedTime;
- public CustomHeader(Context context) {
+ public CustomHeader(Context context, int pinnedTime) {
super(context);
initView();
+ this.mPinnedTime = pinnedTime;
}
public CustomHeader(Context context, AttributeSet attrs) {
@@ -92,8 +94,8 @@ protected void onDraw(Canvas canvas) {
@Override
public void onStateNormal() {
mScale = 1f;
- mDrawable.stop();
-
+ isStop = false;
+// mDrawable.stop();
}
@Override
@@ -109,27 +111,32 @@ public void onStateRefreshing() {
}
@Override
- public void onStateFinish() {
- isStop = true;
- mDrawable.stop();
+ public void onStateFinish(boolean success) {
+ postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ isStop = true;
+ mDrawable.stop();
+ }
+ }, mPinnedTime);
}
private boolean isStop = false;
@Override
- public void onHeaderMove(double offset, int offsetY, int deltaY) {
+ public void onHeaderMove(double headerMovePercent, int offsetY, int deltaY) {
if (isStop) {
return;
}
- mDrawable.setAlpha((int) (255 * offset));
+ mDrawable.setAlpha((int) (255 * headerMovePercent));
mDrawable.showArrow(true);
- float strokeStart = (float) ((offset) * .8f);
+ float strokeStart = (float) ((headerMovePercent) * .8f);
mDrawable.setStartEndTrim(0f, Math.min(0.8f, strokeStart));
- mDrawable.setArrowScale((float) Math.min(1f, offset));
+ mDrawable.setArrowScale((float) Math.min(1f, headerMovePercent));
// magic
- float rotation = (float) ((-0.25f + .4f * offset + offset * 2) * .5f);
+ float rotation = (float) ((-0.25f + .4f * headerMovePercent + headerMovePercent * 2) * .5f);
mDrawable.setProgressRotation(rotation);
invalidate();
@@ -143,7 +150,6 @@ public void setRefreshTime(long lastRefreshTime) {
@Override
public void hide() {
setVisibility(View.GONE);
-
}
@Override
diff --git a/app/src/main/java/com/andview/example/ui/GifView.java b/app/src/main/java/com/andview/example/ui/GifView.java
index 6a837a8..8d2473b 100644
--- a/app/src/main/java/com/andview/example/ui/GifView.java
+++ b/app/src/main/java/com/andview/example/ui/GifView.java
@@ -172,7 +172,8 @@ private void updateAnimationTime() {
private void drawMovieFrame(Canvas canvas) {
// 设置要显示的帧,绘制即可
mMovie.setTime(mCurrentAnimationTime);
- canvas.save(Canvas.MATRIX_SAVE_FLAG);
+ canvas.save();
+// canvas.saveLayer(0, 0, getWidth(), getHeight(), null);
canvas.scale(mScale, mScale);
mMovie.draw(canvas, mLeft / mScale, mTop / mScale);
canvas.restore();
diff --git a/app/src/main/java/com/andview/example/ui/MaterialProgressDrawable.java b/app/src/main/java/com/andview/example/ui/MaterialProgressDrawable.java
index dd7ddf2..5504fe1 100644
--- a/app/src/main/java/com/andview/example/ui/MaterialProgressDrawable.java
+++ b/app/src/main/java/com/andview/example/ui/MaterialProgressDrawable.java
@@ -48,7 +48,7 @@
/**
* Fancy progress indicator for Material theme. It's taken from
- * {@link android.support.v4.widget}. I've done some slight changes.
+ * {@link androidx.core.widget}. I've done some slight changes.
*
*/
public class MaterialProgressDrawable extends Drawable implements Animatable {
diff --git a/app/src/main/java/com/andview/example/ui/NoMoreDataFooterView.java b/app/src/main/java/com/andview/example/ui/NoMoreDataFooterView.java
new file mode 100644
index 0000000..43a30de
--- /dev/null
+++ b/app/src/main/java/com/andview/example/ui/NoMoreDataFooterView.java
@@ -0,0 +1,136 @@
+package com.andview.example.ui;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.andview.refreshview.XRefreshView;
+import com.andview.refreshview.callback.IFooterCallBack;
+import com.andview.refreshview.utils.Utils;
+
+public class NoMoreDataFooterView extends LinearLayout implements IFooterCallBack {
+ private Context mContext;
+
+ private View mContentView;
+ private View mProgressBar;
+ private TextView mHintView;
+ private TextView mClickView;
+ private boolean showing = true;
+
+ public NoMoreDataFooterView(Context context) {
+ super(context);
+ initView(context);
+ }
+
+ public NoMoreDataFooterView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ initView(context);
+ }
+
+ @Override
+ public void callWhenNotAutoLoadMore(final XRefreshView xRefreshView) {
+ View childView = xRefreshView.getChildAt(1);
+ if (childView != null && childView instanceof RecyclerView) {
+ show(Utils.isRecyclerViewFullscreen((RecyclerView) childView));
+ xRefreshView.enableReleaseToLoadMore(Utils.isRecyclerViewFullscreen((RecyclerView) childView));
+ }
+ mClickView.setText(com.andview.refreshview.R.string.xrefreshview_footer_hint_click);
+ mClickView.setOnClickListener(new OnClickListener() {
+
+ @Override
+ public void onClick(View v) {
+ xRefreshView.notifyLoadMore();
+ }
+ });
+ }
+
+ @Override
+ public void onStateReady() {
+ mHintView.setVisibility(View.GONE);
+ mProgressBar.setVisibility(View.GONE);
+ mClickView.setText(com.andview.refreshview.R.string.xrefreshview_footer_hint_click);
+ mClickView.setVisibility(View.VISIBLE);
+// show(true);
+ }
+
+ @Override
+ public void onStateRefreshing() {
+ mHintView.setVisibility(View.GONE);
+ mProgressBar.setVisibility(View.VISIBLE);
+ mClickView.setVisibility(View.GONE);
+ show(true);
+ }
+
+ @Override
+ public void onReleaseToLoadMore() {
+ mHintView.setVisibility(View.GONE);
+ mProgressBar.setVisibility(View.GONE);
+ mClickView.setText(com.andview.refreshview.R.string.xrefreshview_footer_hint_release);
+ mClickView.setVisibility(View.VISIBLE);
+ }
+
+ @Override
+ public void onStateFinish(boolean hideFooter) {
+ if (hideFooter) {
+ mHintView.setText(com.andview.refreshview.R.string.xrefreshview_footer_hint_normal);
+ } else {
+ //处理数据加载失败时ui显示的逻辑,也可以不处理,看自己的需求
+ mHintView.setText("没有更多数据");
+ }
+ mHintView.setVisibility(View.VISIBLE);
+ mProgressBar.setVisibility(View.GONE);
+ mClickView.setVisibility(View.GONE);
+ }
+
+ @Override
+ public void onStateComplete() {
+ mHintView.setText(com.andview.refreshview.R.string.xrefreshview_footer_hint_complete);
+ mHintView.setVisibility(View.VISIBLE);
+ mProgressBar.setVisibility(View.GONE);
+ mClickView.setVisibility(View.GONE);
+ }
+
+ @Override
+ public void show(final boolean show) {
+ if (show == showing) {
+ return;
+ }
+ showing = show;
+ LayoutParams lp = (LayoutParams) mContentView
+ .getLayoutParams();
+ lp.height = show ? LayoutParams.WRAP_CONTENT : 0;
+ mContentView.setLayoutParams(lp);
+// setVisibility(show?VISIBLE:GONE);
+
+ }
+
+ @Override
+ public boolean isShowing() {
+ return showing;
+ }
+
+ private void initView(Context context) {
+ mContext = context;
+ ViewGroup moreView = (ViewGroup) LayoutInflater.from(mContext).inflate(com.andview.refreshview.R.layout.xrefreshview_footer, this);
+ moreView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
+
+ mContentView = moreView.findViewById(com.andview.refreshview.R.id.xrefreshview_footer_content);
+ mProgressBar = moreView
+ .findViewById(com.andview.refreshview.R.id.xrefreshview_footer_progressbar);
+ mHintView = (TextView) moreView
+ .findViewById(com.andview.refreshview.R.id.xrefreshview_footer_hint_textview);
+ mClickView = (TextView) moreView
+ .findViewById(com.andview.refreshview.R.id.xrefreshview_footer_click_textview);
+ }
+
+ @Override
+ public int getFooterHeight() {
+ return getMeasuredHeight();
+ }
+}
diff --git a/app/src/main/java/com/andview/example/ui/raindrop/CustomerFooter.java b/app/src/main/java/com/andview/example/ui/raindrop/CustomerFooter.java
index 1f85f09..66f6712 100644
--- a/app/src/main/java/com/andview/example/ui/raindrop/CustomerFooter.java
+++ b/app/src/main/java/com/andview/example/ui/raindrop/CustomerFooter.java
@@ -1,7 +1,6 @@
package com.andview.example.ui.raindrop;
import android.content.Context;
-import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
@@ -9,6 +8,8 @@
import android.widget.LinearLayout;
import android.widget.TextView;
+import androidx.recyclerview.widget.RecyclerView;
+
import com.andview.refreshview.XRefreshView;
import com.andview.refreshview.callback.IFooterCallBack;
import com.andview.refreshview.utils.Utils;
diff --git a/app/src/main/java/com/andview/example/ui/raindrop/RainDropHeader.java b/app/src/main/java/com/andview/example/ui/raindrop/RainDropHeader.java
index 3e5bf52..963effe 100644
--- a/app/src/main/java/com/andview/example/ui/raindrop/RainDropHeader.java
+++ b/app/src/main/java/com/andview/example/ui/raindrop/RainDropHeader.java
@@ -77,7 +77,7 @@ public void onStateRefreshing() {
}
@Override
- public void onStateFinish() {
+ public void onStateFinish(boolean success) {
}
public int getVisiableHeight() {
diff --git a/app/src/main/java/com/andview/example/ui/smileyloadingview/SmileyHeaderView.java b/app/src/main/java/com/andview/example/ui/smileyloadingview/SmileyHeaderView.java
new file mode 100644
index 0000000..ca613d9
--- /dev/null
+++ b/app/src/main/java/com/andview/example/ui/smileyloadingview/SmileyHeaderView.java
@@ -0,0 +1,140 @@
+package com.andview.example.ui.smileyloadingview;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.os.Build;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.animation.LinearInterpolator;
+import android.widget.LinearLayout;
+import android.widget.Scroller;
+
+import com.andview.example.R;
+import com.andview.refreshview.callback.IHeaderCallBack;
+
+/**
+ * Created by 2144 on 2016/8/26.
+ */
+public class SmileyHeaderView extends LinearLayout implements IHeaderCallBack {
+ public SmileyHeaderView(Context context) {
+ this(context, null);
+ }
+
+ public SmileyHeaderView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public SmileyHeaderView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ init(context);
+ }
+
+ @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+ public SmileyHeaderView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ init(context);
+ }
+
+ private SmileyLoadingView loadingView;
+ private Scroller mScroller;
+
+ private void init(Context context) {
+ View contentView = LayoutInflater.from(context).inflate(R.layout.smiley_headerview, this);
+ loadingView = (SmileyLoadingView) contentView.findViewById(R.id.loading_view);
+ mScroller = new Scroller(getContext(), new LinearInterpolator());
+ }
+
+ @Override
+ public void onStateNormal() {
+ finished = false;
+ }
+
+ @Override
+ public void onStateReady() {
+ }
+
+ @Override
+ public void onStateRefreshing() {
+ refreshing = true;
+ start();
+ }
+
+ @Override
+ public void onStateFinish(boolean success) {
+ refreshing = false;
+ finished = true;
+ mScroller.forceFinished(true);
+ removeCallbacks(mRunnable);
+ loadingView.smile(360 + 180);
+ hasHeaderMove = false;
+ }
+
+ private void start() {
+ if (!refreshing) {
+ return;
+ }
+ loadingView.mRunning = true;
+ if (!hasHeaderMove) {
+ mAngle = 90;
+ }
+ int duration = (int) ((720.0f + 2 * 90 - mAngle) * 2000 / (720.0f + 90));
+ mScroller.startScroll(mAngle, 0, (int) (720.0f + 2 * 90 - mAngle), 0, duration);
+ post(mRunnable);
+ }
+
+
+ private boolean hasHeaderMove = false;
+
+ private AnimalRunnable mRunnable = new AnimalRunnable();
+
+ public class AnimalRunnable implements Runnable {
+
+ @Override
+ public void run() {
+ int curX = mScroller.getCurrX();
+ if (curX != 0)
+ loadingView.smile(curX);
+ if (mScroller.computeScrollOffset()) {
+ post(this);
+ } else {
+ mAngle = 90;
+ loadingView.mRunning = false;
+ start();
+ }
+ }
+ }
+
+ private boolean finished = false;
+ private boolean refreshing = false;
+
+ private int mAngle;
+
+ @Override
+ public void onHeaderMove(double headerMovePercent, int offsetY, int deltaY) {
+ if (finished || refreshing) return;
+ hasHeaderMove = true;
+ if (headerMovePercent <= 1) {
+ mAngle = (int) ((360 + 180 - 90) * headerMovePercent + 90);
+ loadingView.smile(mAngle);
+ }
+ }
+
+ @Override
+ public void setRefreshTime(long lastRefreshTime) {
+
+ }
+
+ public void hide() {
+ setVisibility(View.GONE);
+ }
+
+ public void show() {
+ setVisibility(View.VISIBLE);
+ }
+
+ @Override
+ public int getHeaderHeight() {
+ return getMeasuredHeight();
+ }
+}
diff --git a/app/src/main/java/com/andview/example/ui/smileyloadingview/SmileyLoadingView.java b/app/src/main/java/com/andview/example/ui/smileyloadingview/SmileyLoadingView.java
new file mode 100644
index 0000000..be257fa
--- /dev/null
+++ b/app/src/main/java/com/andview/example/ui/smileyloadingview/SmileyLoadingView.java
@@ -0,0 +1,471 @@
+/**
+ * Copyright 2016 andy
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.andview.example.ui.smileyloadingview;
+
+import android.animation.Animator;
+import android.animation.ValueAnimator;
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.PathMeasure;
+import android.graphics.RectF;
+import android.os.Build;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.animation.LinearInterpolator;
+
+import com.andview.example.R;
+
+/**
+ * Create by andy (https://github.com/andyxialm)
+ * Create time: 16/8/18 10:17
+ *
+ * Modify by huxq17 (https://github.com/huxq17) at 16/8/29 17:30
+ *
+ * Description : SmileyLoadingView
+ */
+public class SmileyLoadingView extends View {
+
+ private static final int DEFAULT_WIDHT = 30;
+ private static final int DEFAULT_HEIGHT = 30;
+ private static final int DEFAULT_PAINT_WIDTH = 5;
+
+ private static final int DEFAULT_ANIM_DURATION = 2000;
+ private static final int DEFAULT_PAINT_COLOR = Color.parseColor("#b3d8f3");
+ private static final int ROTATE_OFFSET = 90;
+
+ private Paint mArcPaint, mCirclePaint;
+ private Path mCirclePath, mArcPath;
+ private RectF mRectF;
+
+ private float[] mCenterPos, mLeftEyePos, mRightEyePos;
+ private float mStartAngle, mSweepAngle;
+ private float mEyeCircleRadius;
+
+ private int mStrokeColor;
+ private int mAnimDuration;
+ private int mAnimRepeatCount;
+
+ private int mStrokeWidth;
+ public boolean mRunning;
+ private boolean mStopping;
+
+ private boolean mFirstStep;
+ private boolean mShowLeftEye, mShowRightEye;
+ private boolean mStopUntilAnimationPerformCompleted;
+
+ private OnAnimPerformCompletedListener mOnAnimPerformCompletedListener;
+ private ValueAnimator mValueAnimator;
+
+ public SmileyLoadingView(Context context) {
+ this(context, null);
+ }
+
+ public SmileyLoadingView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public SmileyLoadingView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ init(attrs);
+ }
+
+ @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+ public SmileyLoadingView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ init(attrs);
+ }
+
+ private void init(AttributeSet attrs) {
+
+ // get attrs
+ TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.SmileyLoadingView);
+ mStrokeColor = ta.getColor(R.styleable.SmileyLoadingView_strokeColor, DEFAULT_PAINT_COLOR);
+ mStrokeWidth = ta.getDimensionPixelSize(R.styleable.SmileyLoadingView_strokeWidth, dp2px(DEFAULT_PAINT_WIDTH));
+ mAnimDuration = ta.getInt(R.styleable.SmileyLoadingView_duration, DEFAULT_ANIM_DURATION);
+ mAnimRepeatCount = ta.getInt(R.styleable.SmileyLoadingView_animRepeatCount, ValueAnimator.INFINITE);
+ ta.recycle();
+
+ mSweepAngle = 180; // init sweepAngle, the mouth line sweep angle
+ mCirclePath = new Path();
+ mArcPath = new Path();
+
+ mArcPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mArcPaint.setStyle(Paint.Style.STROKE);
+ mArcPaint.setStrokeCap(Paint.Cap.ROUND);
+ mArcPaint.setStrokeJoin(Paint.Join.ROUND);
+ mArcPaint.setStrokeWidth(mStrokeWidth);
+ mArcPaint.setColor(mStrokeColor);
+
+ mCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mCirclePaint.setStyle(Paint.Style.STROKE);
+ mCirclePaint.setStrokeCap(Paint.Cap.ROUND);
+ mCirclePaint.setStrokeJoin(Paint.Join.ROUND);
+ mCirclePaint.setStyle(Paint.Style.FILL);
+ mCirclePaint.setColor(mStrokeColor);
+
+ mCenterPos = new float[2];
+ mLeftEyePos = new float[2];
+ mRightEyePos = new float[2];
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ setMeasuredDimension(measureWidthSize(widthMeasureSpec), measureHeightSize(heightMeasureSpec));
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ if (mRunning) {
+ if (mShowLeftEye) {
+ canvas.drawCircle(mLeftEyePos[0], mLeftEyePos[1], mEyeCircleRadius, mCirclePaint);
+ }
+
+ if (mShowRightEye) {
+ canvas.drawCircle(mRightEyePos[0], mRightEyePos[1], mEyeCircleRadius, mCirclePaint);
+ }
+
+ if (mFirstStep) {
+ mArcPath.reset();
+ mArcPath.addArc(mRectF, mStartAngle, mSweepAngle);
+ canvas.drawPath(mArcPath, mArcPaint);
+ } else {
+ mArcPath.reset();
+ mArcPath.addArc(mRectF, mStartAngle, mSweepAngle);
+ canvas.drawPath(mArcPath, mArcPaint);
+ }
+ } else {
+ canvas.drawCircle(mLeftEyePos[0], mLeftEyePos[1], mEyeCircleRadius, mCirclePaint);
+ canvas.drawCircle(mRightEyePos[0], mRightEyePos[1], mEyeCircleRadius, mCirclePaint);
+
+ mArcPath.reset();
+ mArcPath.addArc(mRectF, mStartAngle, mSweepAngle);
+ canvas.drawPath(mArcPath, mArcPaint);
+ }
+ }
+
+ /**
+ * measure width
+ *
+ * @param measureSpec spec
+ * @return width
+ */
+ private int measureWidthSize(int measureSpec) {
+ int defSize = dp2px(DEFAULT_WIDHT);
+ int specSize = MeasureSpec.getSize(measureSpec);
+ int specMode = MeasureSpec.getMode(measureSpec);
+
+ int result = 0;
+ switch (specMode) {
+ case MeasureSpec.UNSPECIFIED:
+ case MeasureSpec.AT_MOST:
+ result = Math.min(defSize, specSize);
+ break;
+ case MeasureSpec.EXACTLY:
+ result = specSize;
+ break;
+ }
+ return result;
+ }
+
+ /**
+ * measure height
+ *
+ * @param measureSpec spec
+ * @return height
+ */
+ private int measureHeightSize(int measureSpec) {
+ int defSize = dp2px(DEFAULT_HEIGHT);
+ int specSize = MeasureSpec.getSize(measureSpec);
+ int specMode = MeasureSpec.getMode(measureSpec);
+
+ int result = 0;
+ switch (specMode) {
+ case MeasureSpec.UNSPECIFIED:
+ case MeasureSpec.AT_MOST:
+ result = Math.min(defSize, specSize);
+ break;
+ case MeasureSpec.EXACTLY:
+ result = specSize;
+ break;
+ }
+ return result;
+ }
+
+ @Override
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ super.onSizeChanged(w, h, oldw, oldh);
+ int paddingLeft = getPaddingLeft();
+ int paddingRight = getPaddingRight();
+ int paddingTop = getPaddingTop();
+ int paddingBottom = getPaddingBottom();
+
+ int width = getWidth();
+ int height = getHeight();
+ mCenterPos[0] = (width - paddingRight + paddingLeft) >> 1;
+ mCenterPos[1] = (height - paddingBottom + paddingTop) >> 1;
+
+
+ float radiusX = (width - paddingRight - paddingLeft - mStrokeWidth) >> 1;
+ float radiusY = (height - paddingTop - paddingBottom - mStrokeWidth) >> 1;
+ float radius = Math.min(radiusX, radiusY);
+ mEyeCircleRadius = mStrokeWidth / 2;
+
+ mRectF = new RectF(paddingLeft + mStrokeWidth, paddingTop + mStrokeWidth,
+ width - mStrokeWidth - paddingRight, height - mStrokeWidth - paddingBottom);
+
+ mArcPath.arcTo(mRectF, 0, 180);
+ mCirclePath.addCircle(mCenterPos[0], mCenterPos[1], radius, Path.Direction.CW);
+ PathMeasure circlePathMeasure = new PathMeasure(mCirclePath, true);
+
+ circlePathMeasure.getPosTan(circlePathMeasure.getLength() / 8 * 5, mLeftEyePos, null);
+ circlePathMeasure.getPosTan(circlePathMeasure.getLength() / 8 * 7, mRightEyePos, null);
+ mLeftEyePos[0] += mStrokeWidth >> 2;
+ mLeftEyePos[1] += mStrokeWidth >> 1;
+ mRightEyePos[0] -= mStrokeWidth >> 2;
+ mRightEyePos[1] += mStrokeWidth >> 1;
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ if (mValueAnimator != null && mValueAnimator.isRunning()) {
+ mValueAnimator.end();
+ }
+ }
+
+ /**
+ * Set paint color alpha
+ *
+ * @param alpha alpha
+ */
+ public void setPaintAlpha(int alpha) {
+ mArcPaint.setAlpha(alpha);
+ mCirclePaint.setAlpha(alpha);
+ invalidate();
+ }
+
+ /**
+ * Set paint stroke color
+ *
+ * @param color color
+ */
+ public void setStrokeColor(int color) {
+ mStrokeColor = color;
+ invalidate();
+ }
+
+ /**
+ * Set paint stroke width
+ *
+ * @param width px
+ */
+ public void setStrokeWidth(int width) {
+ mStrokeWidth = width;
+ }
+
+ /**
+ * Set animation running duration
+ *
+ * @param duration duration
+ */
+ @SuppressWarnings("unused")
+ public void setAnimDuration(int duration) {
+ mAnimDuration = duration;
+ }
+
+ /**
+ * Set animation repeat count, ValueAnimator.INFINITE(-1) means cycle
+ *
+ * @param repeatCount repeat count
+ */
+ @SuppressWarnings("unused")
+ public void setAnimRepeatCount(int repeatCount) {
+ mAnimRepeatCount = repeatCount;
+ }
+
+ public void start(int animRepeatCount) {
+ if (mRunning) {
+ return;
+ }
+ mAnimRepeatCount = animRepeatCount;
+
+ mFirstStep = true;
+
+ mValueAnimator = ValueAnimator.ofFloat(ROTATE_OFFSET, 720.0f + 2 * ROTATE_OFFSET);
+ mValueAnimator.setDuration(mAnimDuration);
+ mValueAnimator.setInterpolator(new LinearInterpolator());
+ mValueAnimator.setRepeatCount(mAnimRepeatCount);
+ mValueAnimator.setRepeatMode(ValueAnimator.RESTART);
+ mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ if (!animation.isRunning()) {
+ return;
+ }
+ float animatedValue = (float) animation.getAnimatedValue();
+ update(animatedValue);
+ }
+ });
+ mValueAnimator.addListener(new Animator.AnimatorListener() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ mRunning = true;
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mRunning = false;
+ mStopping = false;
+ if (mOnAnimPerformCompletedListener != null) {
+ mOnAnimPerformCompletedListener.onCompleted();
+ }
+ reset();
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ mRunning = false;
+ mStopping = false;
+ if (mOnAnimPerformCompletedListener != null) {
+ mOnAnimPerformCompletedListener.onCompleted();
+ }
+ reset();
+ }
+
+ @Override
+ public void onAnimationRepeat(Animator animation) {
+ if (mStopUntilAnimationPerformCompleted) {
+ animation.cancel();
+ mStopUntilAnimationPerformCompleted = false;
+ }
+ }
+ });
+ mValueAnimator.start();
+ }
+
+ private void update(float angle) {
+ mFirstStep = angle / 360.0f <= 1;
+ if (mFirstStep) {
+ mShowLeftEye = angle % 360 > 225.0f;
+ mShowRightEye = angle % 360 > 315.0f;
+
+ // set arc sweep angle when the step is first, set value: 0.1f similar to a circle
+ mSweepAngle = 0.1f;
+ mStartAngle = angle;
+ } else {
+ mShowLeftEye = (angle / 360.0f <= 2) && angle % 360 <= 225.0f;
+ mShowRightEye = (angle / 360.0f <= 2) && angle % 360 <= 315.0f;
+ if (angle >= (720.0f + ROTATE_OFFSET)) {
+ mStartAngle = angle - (720.0f + ROTATE_OFFSET);
+ mSweepAngle = ROTATE_OFFSET - mStartAngle;
+ } else {
+ mStartAngle = (angle / 360.0f <= 1.625) ? 0 : angle - mSweepAngle - 360;
+ mSweepAngle = (angle / 360.0f <= 1.625) ? angle % 360 : 225 - (angle - 225 - 360) / 5 * 3;
+ }
+ }
+ invalidate();
+ }
+
+ /**
+ * smile
+ *
+ * @param angle
+ */
+ public void smile(float angle) {
+ update(angle);
+ }
+
+ /**
+ * Start animation
+ */
+ public void start() {
+ start(ValueAnimator.INFINITE);
+ }
+
+ /**
+ * Stop animation
+ */
+ public void stop() {
+ stop(true);
+ }
+
+ /**
+ * stop it after animation perform completed
+ *
+ * @param stopUntilAnimationPerformCompleted boolean
+ */
+ public void stop(boolean stopUntilAnimationPerformCompleted) {
+ if (mStopping || mValueAnimator == null || !mValueAnimator.isRunning()) {
+ return;
+ }
+ mStopping = stopUntilAnimationPerformCompleted;
+
+ mStopUntilAnimationPerformCompleted = stopUntilAnimationPerformCompleted;
+ if (mValueAnimator != null && mValueAnimator.isRunning()) {
+ if (!stopUntilAnimationPerformCompleted) {
+ mValueAnimator.end();
+ }
+ } else {
+ mStopping = false;
+ if (mOnAnimPerformCompletedListener != null) {
+ mOnAnimPerformCompletedListener.onCompleted();
+ }
+ }
+ }
+
+ /**
+ * set status changed listener
+ *
+ * @param l OnStatusChangedListener
+ */
+ public void setOnAnimPerformCompletedListener(OnAnimPerformCompletedListener l) {
+ mOnAnimPerformCompletedListener = l;
+ }
+
+ /**
+ * reset UI
+ */
+ private void reset() {
+ mStartAngle = 0;
+ mSweepAngle = 180;
+ invalidate();
+ }
+
+ /**
+ * dp to px
+ *
+ * @param dpValue dp
+ * @return px
+ */
+ private int dp2px(float dpValue) {
+ final float scale = getContext().getResources().getDisplayMetrics().density;
+ return (int) (dpValue * scale + 0.5f);
+ }
+
+ /**
+ * Callback
+ */
+ public interface OnAnimPerformCompletedListener {
+ void onCompleted();
+ }
+}
diff --git a/app/src/main/java/com/andview/example/view/EatPluseView.java b/app/src/main/java/com/andview/example/view/EatPluseView.java
new file mode 100644
index 0000000..b946539
--- /dev/null
+++ b/app/src/main/java/com/andview/example/view/EatPluseView.java
@@ -0,0 +1,120 @@
+package com.andview.example.view;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.RectF;
+import android.os.Handler;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.View;
+
+/**
+ * Author: fanyafeng
+ * Date: 17/9/28 下午1:46
+ * Email: fanyafeng@live.cn
+ */
+public class EatPluseView extends View {
+
+ private static final String TAG = EatPluseView.class.getSimpleName();
+
+ private static int width = 0;
+ private static int height = 0;
+
+ private final static int sunR = 120;
+ private Paint sunPaint;
+ private int sunX;
+ private int sunY;
+ private static RectF sunRectF;
+
+ private int startAngle = 0;
+ private int swipeAngle = 360;
+
+ private boolean isAdd = true;
+
+ private int pluseR;
+
+ public EatPluseView(Context context) {
+ super(context);
+ init();
+ }
+
+ public EatPluseView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init();
+ }
+
+ public EatPluseView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ init();
+ }
+
+ private void init() {
+ sunPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ sunPaint.setAntiAlias(true);
+ sunPaint.setColor(Color.BLUE);
+ sunPaint.setStyle(Paint.Style.FILL);
+ sunPaint.setStrokeWidth(1);
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+ if (width == 0) {
+ width = getWidth();
+ }
+ if (height == 0) {
+ height = getHeight();
+ }
+
+ if (sunX == 0) {
+ sunX = width / 2;
+ }
+ if (sunY == 0) {
+ sunY = height / 2;
+ }
+ Log.d(TAG, "宽度:" + width + "高度:" + height);
+
+ Log.d(TAG, "sunX - sunR:" + (sunX - sunR) + " sunY - sunR:" + (sunY - sunR) + " sunX + sunR:" + (sunX + sunR) + " sunY - sunR:" + (sunY + sunR));
+ if (sunRectF == null) {
+ sunRectF = new RectF(0, sunY - sunR, 2 * sunR, sunY + sunR);
+
+ pluseR = sunR * 11 / 6 + sunR;
+ }
+
+ canvas.drawArc(sunRectF, startAngle, swipeAngle, true, sunPaint);
+
+ canvas.drawCircle(pluseR, sunY, sunR / 6, sunPaint);
+ if (pluseR <= sunR * 5 / 6) {
+ pluseR = sunR * 11 / 6 + sunR;
+ } else {
+ pluseR -= 4;
+ }
+ if (!isAdd) {
+ startAngle--;
+ swipeAngle += 2;
+ } else {
+ startAngle++;
+ swipeAngle -= 2;
+ }
+
+ if (startAngle == 30) {
+ isAdd = false;
+ }
+
+ if (startAngle == 0) {
+ isAdd = true;
+ }
+
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ invalidate();
+ }
+ }, 10);
+
+ }
+
+
+}
diff --git a/app/src/main/java/com/andview/example/view/XRefreshViewCarHeader.java b/app/src/main/java/com/andview/example/view/XRefreshViewCarHeader.java
new file mode 100644
index 0000000..c69de7e
--- /dev/null
+++ b/app/src/main/java/com/andview/example/view/XRefreshViewCarHeader.java
@@ -0,0 +1,112 @@
+package com.andview.example.view;
+
+import android.content.Context;
+import android.graphics.drawable.AnimationDrawable;
+import android.os.Handler;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.Animation;
+import android.view.animation.ScaleAnimation;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.andview.example.DensityUtil;
+import com.andview.example.R;
+import com.andview.refreshview.callback.IHeaderCallBack;
+
+/**
+ * Author: fanyafeng
+ * Date: 18/10/1 下午5:17
+ * Email: fanyafeng@live.cn
+ */
+public class XRefreshViewCarHeader extends LinearLayout implements IHeaderCallBack {
+ private ViewGroup mContent;
+
+ private ImageView ivStatus;
+ private TextView tvStatus;
+
+ private float startPoint = 0;
+ private float endPoint = 0;
+
+ public XRefreshViewCarHeader(Context context) {
+ super(context);
+ initView(context);
+ }
+
+ /**
+ * @param context
+ * @param attrs
+ */
+ public XRefreshViewCarHeader(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ initView(context);
+ }
+
+ private void initView(Context context) {
+ mContent = (ViewGroup) LayoutInflater.from(context).inflate(R.layout.xrefreshview_car_header, this);
+ tvStatus = (TextView) mContent.findViewById(R.id.tvStatus);
+ ivStatus = (ImageView) mContent.findViewById(R.id.ivStatus);
+ }
+
+ /**
+ * hide footer when disable pull load more
+ */
+ public void hide() {
+ setVisibility(View.GONE);
+ }
+
+ public void show() {
+ setVisibility(View.VISIBLE);
+ }
+
+ @Override
+ public void onStateNormal() {
+ tvStatus.setText("下拉刷新查看状态");
+ ivStatus.setImageResource(R.drawable.colors_refresh_icon);
+ }
+
+ @Override
+ public void onStateReady() {
+ tvStatus.setText("松手后刷新");
+ ivStatus.setImageResource(R.drawable.colors_refresh_icon);
+ }
+
+ @Override
+ public void onStateRefreshing() {
+ tvStatus.setText("正在刷新");
+ ivStatus.setImageResource(R.drawable.colors_refresh_loading);
+ ((AnimationDrawable) ivStatus.getDrawable()).start();
+ }
+
+ @Override
+ public void onStateFinish(boolean success) {
+ if (success) {
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ tvStatus.setText("刷新完成");
+ ivStatus.setImageResource(R.drawable.colors_refresh_icon);
+ }
+ }, 1000);
+ }
+ }
+
+ @Override
+ public void onHeaderMove(double offset, int offsetY, int deltaY) {
+ Log.d("offsetY", "y轴滑动距离 offsetY:" + offsetY + "对应的距离73dp:" + DensityUtil.dip2px(getContext(), 73));
+ }
+
+ @Override
+ public void setRefreshTime(long lastRefreshTime) {
+
+ }
+
+ @Override
+ public int getHeaderHeight() {
+ return getMeasuredHeight();
+ }
+}
diff --git a/app/src/main/java/com/andview/example/view/XRefreshViewJDHeader.java b/app/src/main/java/com/andview/example/view/XRefreshViewJDHeader.java
new file mode 100644
index 0000000..ba64398
--- /dev/null
+++ b/app/src/main/java/com/andview/example/view/XRefreshViewJDHeader.java
@@ -0,0 +1,147 @@
+package com.andview.example.view;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.drawable.AnimationDrawable;
+import android.os.Handler;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.Animation;
+import android.view.animation.RotateAnimation;
+import android.view.animation.ScaleAnimation;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+
+import com.andview.example.DensityUtil;
+import com.andview.example.R;
+import com.andview.refreshview.callback.IHeaderCallBack;
+import com.andview.refreshview.utils.Utils;
+
+import java.util.Calendar;
+
+public class XRefreshViewJDHeader extends LinearLayout implements IHeaderCallBack {
+ private ViewGroup mContent;
+
+ private ImageView ivPerson;
+ private ImageView ivPackage;
+
+ private float startPoint = 0;
+ private float endPoint = 0;
+
+ public XRefreshViewJDHeader(Context context) {
+ super(context);
+ initView(context);
+ }
+
+ /**
+ * @param context
+ * @param attrs
+ */
+ public XRefreshViewJDHeader(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ initView(context);
+ }
+
+ private void initView(Context context) {
+ mContent = (ViewGroup) LayoutInflater.from(context).inflate(R.layout.xrefreshview_jd_header, this);
+ ivPackage = (ImageView) mContent.findViewById(R.id.ivPackage);
+ ivPerson = (ImageView) mContent.findViewById(R.id.ivPerson);
+ }
+
+ /**
+ * hide footer when disable pull load more
+ */
+ public void hide() {
+ setVisibility(View.GONE);
+ }
+
+ public void show() {
+ setVisibility(View.VISIBLE);
+ }
+
+ @Override
+ public void onStateNormal() {
+ ivPackage.setImageResource(R.drawable.jd_package);
+ ivPerson.setImageResource(R.drawable.jd_person);
+ }
+
+ @Override
+ public void onStateReady() {
+ ivPackage.setImageResource(R.drawable.jd_package);
+ ivPerson.setImageResource(R.drawable.jd_person);
+ }
+
+ @Override
+ public void onStateRefreshing() {
+ ivPackage.setImageDrawable(null);
+ ivPerson.setImageResource(R.drawable.jd_loading);
+ ((AnimationDrawable) ivPerson.getDrawable()).start();
+ }
+
+ @Override
+ public void onStateFinish(boolean success) {
+ if (success) {
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ ivPackage.setImageResource(R.drawable.jd_package);
+ ivPerson.setImageResource(R.drawable.jd_person);
+ }
+ }, 1000);
+ }
+ }
+
+ @Override
+ public void onHeaderMove(double offset, int offsetY, int deltaY) {
+ Log.d("offsetY", "y轴滑动距离 offsetY:" + offsetY + "对应的距离73dp:" + DensityUtil.dip2px(getContext(), 73));
+
+ startPoint = endPoint;
+ endPoint = (float) offsetY / (float) DensityUtil.dip2px(getContext(), 73);
+
+ if (endPoint <= 1) {
+
+ ScaleAnimation scaleAnimation = new ScaleAnimation(startPoint, endPoint, startPoint, endPoint, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
+ scaleAnimation.setFillAfter(true);
+ ivPackage.startAnimation(scaleAnimation);
+
+ ScaleAnimation scaleAnimationPerson = new ScaleAnimation(startPoint, endPoint, startPoint, endPoint, Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0.5f);
+ scaleAnimationPerson.setFillAfter(true);
+ ivPerson.startAnimation(scaleAnimationPerson);
+ }
+
+ if (startPoint != endPoint) {
+ startPoint = endPoint;
+ }
+ }
+
+ @Override
+ public void setRefreshTime(long lastRefreshTime) {
+ // 获取当前时间
+ Calendar mCalendar = Calendar.getInstance();
+ long refreshTime = mCalendar.getTimeInMillis();
+ long howLong = refreshTime - lastRefreshTime;
+ int minutes = (int) (howLong / 1000 / 60);
+ String refreshTimeText = null;
+ Resources resources = getContext().getResources();
+ if (minutes < 1) {
+ refreshTimeText = resources.getString(R.string.xrefreshview_refresh_justnow);
+ } else if (minutes < 60) {
+ refreshTimeText = resources.getString(R.string.xrefreshview_refresh_minutes_ago);
+ refreshTimeText = Utils.format(refreshTimeText, minutes);
+ } else if (minutes < 60 * 24) {
+ refreshTimeText = resources.getString(R.string.xrefreshview_refresh_hours_ago);
+ refreshTimeText = Utils.format(refreshTimeText, minutes / 60);
+ } else {
+ refreshTimeText = resources.getString(R.string.xrefreshview_refresh_days_ago);
+ refreshTimeText = Utils.format(refreshTimeText, minutes / 60 / 24);
+ }
+ }
+
+ @Override
+ public int getHeaderHeight() {
+ return getMeasuredHeight();
+ }
+}
diff --git a/app/src/main/java/com/andview/example/view/XRefreshViewWineHeader.java b/app/src/main/java/com/andview/example/view/XRefreshViewWineHeader.java
new file mode 100644
index 0000000..374dbdb
--- /dev/null
+++ b/app/src/main/java/com/andview/example/view/XRefreshViewWineHeader.java
@@ -0,0 +1,141 @@
+package com.andview.example.view;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.drawable.AnimationDrawable;
+import android.os.Handler;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.Animation;
+import android.view.animation.RotateAnimation;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+
+import com.andview.example.R;
+import com.andview.refreshview.callback.IHeaderCallBack;
+import com.andview.refreshview.utils.Utils;
+
+import java.util.Calendar;
+
+public class XRefreshViewWineHeader extends LinearLayout implements IHeaderCallBack {
+ private ViewGroup mContent;
+ // private ImageView mArrowImageView;
+ private ImageView mOkImageView;
+ private View layoutTop;
+ // private ProgressBar mProgressBar;
+// private TextView mHintTextView;
+// private TextView mHeaderTimeTextView;
+ private Animation mRotateUpAnim;
+ private Animation mRotateDownAnim;
+ private final int ROTATE_ANIM_DURATION = 180;
+
+ public XRefreshViewWineHeader(Context context) {
+ super(context);
+ initView(context, true);
+ }
+
+ public XRefreshViewWineHeader(Context context, boolean isAddHeaderTop) {
+ super(context);
+ initView(context, isAddHeaderTop);
+ }
+
+ /**
+ * @param context
+ * @param attrs
+ */
+ public XRefreshViewWineHeader(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ initView(context, true);
+ }
+
+ private void initView(Context context, boolean isAddHeaderTop) {
+ mContent = (ViewGroup) LayoutInflater.from(context).inflate(R.layout.xrefreshview_wine_header, this);
+ mOkImageView = (ImageView) findViewById(R.id.xrefreshview_header_ok);
+ layoutTop = findViewById(R.id.layout_top);
+ layoutTop.setVisibility(isAddHeaderTop ? VISIBLE : GONE);
+
+ mOkImageView.setImageResource(R.drawable.wine_loading);
+ mRotateUpAnim = new RotateAnimation(0.0f, -180.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
+ mRotateUpAnim.setDuration(ROTATE_ANIM_DURATION);
+ mRotateUpAnim.setFillAfter(true);
+ mRotateDownAnim = new RotateAnimation(-180.0f, 0.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
+ mRotateDownAnim.setDuration(ROTATE_ANIM_DURATION);
+ mRotateDownAnim.setFillAfter(true);
+ }
+
+ public void setRefreshTime(long lastRefreshTime) {
+ // 获取当前时间
+ Calendar mCalendar = Calendar.getInstance();
+ long refreshTime = mCalendar.getTimeInMillis();
+ long howLong = refreshTime - lastRefreshTime;
+ int minutes = (int) (howLong / 1000 / 60);
+ String refreshTimeText = null;
+ Resources resources = getContext().getResources();
+ if (minutes < 1) {
+ refreshTimeText = resources.getString(R.string.xrefreshview_refresh_justnow);
+ } else if (minutes < 60) {
+ refreshTimeText = resources.getString(R.string.xrefreshview_refresh_minutes_ago);
+ refreshTimeText = Utils.format(refreshTimeText, minutes);
+ } else if (minutes < 60 * 24) {
+ refreshTimeText = resources.getString(R.string.xrefreshview_refresh_hours_ago);
+ refreshTimeText = Utils.format(refreshTimeText, minutes / 60);
+ } else {
+ refreshTimeText = resources.getString(R.string.xrefreshview_refresh_days_ago);
+ refreshTimeText = Utils.format(refreshTimeText, minutes / 60 / 24);
+ }
+ }
+
+ /**
+ * hide footer when disable pull load more
+ */
+ public void hide() {
+ setVisibility(View.GONE);
+ }
+
+ public void show() {
+ setVisibility(View.VISIBLE);
+ }
+
+ @Override
+ public void onStateNormal() {
+ mOkImageView.setVisibility(View.VISIBLE);
+ ((AnimationDrawable) mOkImageView.getDrawable()).stop();
+ }
+
+ @Override
+ public void onStateReady() {
+ mOkImageView.setVisibility(View.VISIBLE);
+ ((AnimationDrawable) mOkImageView.getDrawable()).stop();
+ }
+
+ @Override
+ public void onStateRefreshing() {
+ mOkImageView.setVisibility(View.VISIBLE);
+ ((AnimationDrawable) mOkImageView.getDrawable()).start();
+ }
+
+ @Override
+ public void onStateFinish(boolean success) {
+ if (success) {
+ new Handler().postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ mOkImageView.setVisibility(View.VISIBLE);
+ ((AnimationDrawable) mOkImageView.getDrawable()).stop();
+ }
+ }, 1000);
+ }
+ }
+
+ @Override
+ public void onHeaderMove(double offset, int offsetY, int deltaY) {
+
+ }
+
+ @Override
+ public int getHeaderHeight() {
+ return getMeasuredHeight();
+ }
+}
diff --git a/app/src/main/res/drawable-xhdpi/colors_refresh_00.png b/app/src/main/res/drawable-xhdpi/colors_refresh_00.png
new file mode 100644
index 0000000..690c423
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/colors_refresh_00.png differ
diff --git a/app/src/main/res/drawable-xhdpi/colors_refresh_01.png b/app/src/main/res/drawable-xhdpi/colors_refresh_01.png
new file mode 100644
index 0000000..e27b474
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/colors_refresh_01.png differ
diff --git a/app/src/main/res/drawable-xhdpi/colors_refresh_02.png b/app/src/main/res/drawable-xhdpi/colors_refresh_02.png
new file mode 100644
index 0000000..b3698ec
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/colors_refresh_02.png differ
diff --git a/app/src/main/res/drawable-xhdpi/colors_refresh_03.png b/app/src/main/res/drawable-xhdpi/colors_refresh_03.png
new file mode 100644
index 0000000..e676cd8
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/colors_refresh_03.png differ
diff --git a/app/src/main/res/drawable-xhdpi/colors_refresh_04.png b/app/src/main/res/drawable-xhdpi/colors_refresh_04.png
new file mode 100644
index 0000000..b7a54fa
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/colors_refresh_04.png differ
diff --git a/app/src/main/res/drawable-xhdpi/colors_refresh_05.png b/app/src/main/res/drawable-xhdpi/colors_refresh_05.png
new file mode 100644
index 0000000..9ea3e92
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/colors_refresh_05.png differ
diff --git a/app/src/main/res/drawable-xhdpi/colors_refresh_06.png b/app/src/main/res/drawable-xhdpi/colors_refresh_06.png
new file mode 100644
index 0000000..d273ee9
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/colors_refresh_06.png differ
diff --git a/app/src/main/res/drawable-xhdpi/colors_refresh_07.png b/app/src/main/res/drawable-xhdpi/colors_refresh_07.png
new file mode 100644
index 0000000..641bd0f
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/colors_refresh_07.png differ
diff --git a/app/src/main/res/drawable-xhdpi/colors_refresh_08.png b/app/src/main/res/drawable-xhdpi/colors_refresh_08.png
new file mode 100644
index 0000000..1f19bb4
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/colors_refresh_08.png differ
diff --git a/app/src/main/res/drawable-xhdpi/colors_refresh_09.png b/app/src/main/res/drawable-xhdpi/colors_refresh_09.png
new file mode 100644
index 0000000..8ae9f88
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/colors_refresh_09.png differ
diff --git a/app/src/main/res/drawable-xhdpi/colors_refresh_10.png b/app/src/main/res/drawable-xhdpi/colors_refresh_10.png
new file mode 100644
index 0000000..2376e2c
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/colors_refresh_10.png differ
diff --git a/app/src/main/res/drawable-xhdpi/colors_refresh_11.png b/app/src/main/res/drawable-xhdpi/colors_refresh_11.png
new file mode 100644
index 0000000..d0cab7a
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/colors_refresh_11.png differ
diff --git a/app/src/main/res/drawable-xhdpi/colors_refresh_12.png b/app/src/main/res/drawable-xhdpi/colors_refresh_12.png
new file mode 100644
index 0000000..4080956
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/colors_refresh_12.png differ
diff --git a/app/src/main/res/drawable-xhdpi/colors_refresh_13.png b/app/src/main/res/drawable-xhdpi/colors_refresh_13.png
new file mode 100644
index 0000000..61422a6
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/colors_refresh_13.png differ
diff --git a/app/src/main/res/drawable-xhdpi/colors_refresh_14.png b/app/src/main/res/drawable-xhdpi/colors_refresh_14.png
new file mode 100644
index 0000000..a08a80f
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/colors_refresh_14.png differ
diff --git a/app/src/main/res/drawable-xhdpi/colors_refresh_15.png b/app/src/main/res/drawable-xhdpi/colors_refresh_15.png
new file mode 100644
index 0000000..0eb7de0
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/colors_refresh_15.png differ
diff --git a/app/src/main/res/drawable-xhdpi/colors_refresh_16.png b/app/src/main/res/drawable-xhdpi/colors_refresh_16.png
new file mode 100644
index 0000000..414f3d9
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/colors_refresh_16.png differ
diff --git a/app/src/main/res/drawable-xhdpi/colors_refresh_17.png b/app/src/main/res/drawable-xhdpi/colors_refresh_17.png
new file mode 100644
index 0000000..0f6398f
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/colors_refresh_17.png differ
diff --git a/app/src/main/res/drawable-xhdpi/colors_refresh_18.png b/app/src/main/res/drawable-xhdpi/colors_refresh_18.png
new file mode 100644
index 0000000..34a8183
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/colors_refresh_18.png differ
diff --git a/app/src/main/res/drawable-xhdpi/colors_refresh_19.png b/app/src/main/res/drawable-xhdpi/colors_refresh_19.png
new file mode 100644
index 0000000..1f1a931
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/colors_refresh_19.png differ
diff --git a/app/src/main/res/drawable-xhdpi/colors_refresh_20.png b/app/src/main/res/drawable-xhdpi/colors_refresh_20.png
new file mode 100644
index 0000000..bb8ad7f
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/colors_refresh_20.png differ
diff --git a/app/src/main/res/drawable-xhdpi/colors_refresh_21.png b/app/src/main/res/drawable-xhdpi/colors_refresh_21.png
new file mode 100644
index 0000000..e196ef8
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/colors_refresh_21.png differ
diff --git a/app/src/main/res/drawable-xhdpi/colors_refresh_22.png b/app/src/main/res/drawable-xhdpi/colors_refresh_22.png
new file mode 100644
index 0000000..9b7f401
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/colors_refresh_22.png differ
diff --git a/app/src/main/res/drawable-xhdpi/colors_refresh_23.png b/app/src/main/res/drawable-xhdpi/colors_refresh_23.png
new file mode 100644
index 0000000..6ef0be6
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/colors_refresh_23.png differ
diff --git a/app/src/main/res/drawable-xhdpi/colors_refresh_24.png b/app/src/main/res/drawable-xhdpi/colors_refresh_24.png
new file mode 100644
index 0000000..27087c1
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/colors_refresh_24.png differ
diff --git a/app/src/main/res/drawable-xhdpi/colors_refresh_25.png b/app/src/main/res/drawable-xhdpi/colors_refresh_25.png
new file mode 100644
index 0000000..58e6f71
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/colors_refresh_25.png differ
diff --git a/app/src/main/res/drawable-xhdpi/colors_refresh_icon.png b/app/src/main/res/drawable-xhdpi/colors_refresh_icon.png
new file mode 100644
index 0000000..cb4cbf7
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/colors_refresh_icon.png differ
diff --git a/app/src/main/res/drawable-xhdpi/jd_package.png b/app/src/main/res/drawable-xhdpi/jd_package.png
new file mode 100755
index 0000000..5e9a8fa
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/jd_package.png differ
diff --git a/app/src/main/res/drawable-xhdpi/jd_person.png b/app/src/main/res/drawable-xhdpi/jd_person.png
new file mode 100755
index 0000000..0b8ef69
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/jd_person.png differ
diff --git a/app/src/main/res/drawable-xhdpi/jd_person_package_1.png b/app/src/main/res/drawable-xhdpi/jd_person_package_1.png
new file mode 100755
index 0000000..2d4840c
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/jd_person_package_1.png differ
diff --git a/app/src/main/res/drawable-xhdpi/jd_person_package_2.png b/app/src/main/res/drawable-xhdpi/jd_person_package_2.png
new file mode 100755
index 0000000..3729a72
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/jd_person_package_2.png differ
diff --git a/app/src/main/res/drawable-xhdpi/jd_person_package_3.png b/app/src/main/res/drawable-xhdpi/jd_person_package_3.png
new file mode 100755
index 0000000..c077683
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/jd_person_package_3.png differ
diff --git a/app/src/main/res/drawable-xhdpi/loading_1.png b/app/src/main/res/drawable-xhdpi/loading_1.png
new file mode 100755
index 0000000..fad6cb5
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/loading_1.png differ
diff --git a/app/src/main/res/drawable-xhdpi/loading_2.png b/app/src/main/res/drawable-xhdpi/loading_2.png
new file mode 100755
index 0000000..bfa7518
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/loading_2.png differ
diff --git a/app/src/main/res/drawable-xhdpi/water_point_left.png b/app/src/main/res/drawable-xhdpi/water_point_left.png
new file mode 100755
index 0000000..c07c2ce
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/water_point_left.png differ
diff --git a/app/src/main/res/drawable-xhdpi/water_point_right.png b/app/src/main/res/drawable-xhdpi/water_point_right.png
new file mode 100755
index 0000000..584e8bb
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/water_point_right.png differ
diff --git a/app/src/main/res/drawable/colors_refresh_loading.xml b/app/src/main/res/drawable/colors_refresh_loading.xml
new file mode 100644
index 0000000..6a0b205
--- /dev/null
+++ b/app/src/main/res/drawable/colors_refresh_loading.xml
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/jd_loading.xml b/app/src/main/res/drawable/jd_loading.xml
new file mode 100644
index 0000000..ffd59e8
--- /dev/null
+++ b/app/src/main/res/drawable/jd_loading.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/wine_loading.xml b/app/src/main/res/drawable/wine_loading.xml
new file mode 100644
index 0000000..d7c2e7a
--- /dev/null
+++ b/app/src/main/res/drawable/wine_loading.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_car_crm.xml b/app/src/main/res/layout/activity_car_crm.xml
new file mode 100644
index 0000000..c2a0f69
--- /dev/null
+++ b/app/src/main/res/layout/activity_car_crm.xml
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_customview.xml b/app/src/main/res/layout/activity_customview.xml
index 8dcd504..bbfc007 100644
--- a/app/src/main/res/layout/activity_customview.xml
+++ b/app/src/main/res/layout/activity_customview.xml
@@ -1,11 +1,10 @@
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_gridview.xml b/app/src/main/res/layout/activity_gridview.xml
index a44caba..e9aec0d 100644
--- a/app/src/main/res/layout/activity_gridview.xml
+++ b/app/src/main/res/layout/activity_gridview.xml
@@ -1,10 +1,9 @@
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 9ad50d2..08f278a 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -1,5 +1,4 @@
@@ -36,20 +35,20 @@
android:text="自定义view" />
+ android:text="ScrollView" />
+ android:text="使用空布局" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_scrollview.xml b/app/src/main/res/layout/activity_scrollview.xml
index 7ecf080..93aa96c 100644
--- a/app/src/main/res/layout/activity_scrollview.xml
+++ b/app/src/main/res/layout/activity_scrollview.xml
@@ -1,23 +1,6 @@
-
+ android:layout_height="match_parent">
-
-
-
-
-
-
-
\ No newline at end of file
+
diff --git a/app/src/main/res/layout/activity_tao_bao.xml b/app/src/main/res/layout/activity_tao_bao.xml
new file mode 100644
index 0000000..acce054
--- /dev/null
+++ b/app/src/main/res/layout/activity_tao_bao.xml
@@ -0,0 +1,13 @@
+
+
+
+
diff --git a/app/src/main/res/layout/activity_webview.xml b/app/src/main/res/layout/activity_webview.xml
index 1d9f6e7..2593465 100644
--- a/app/src/main/res/layout/activity_webview.xml
+++ b/app/src/main/res/layout/activity_webview.xml
@@ -9,7 +9,7 @@
xrefreshview:isHeightMatchParent="true"
xrefreshview:isWidthMatchParent="true" >
-
diff --git a/app/src/main/res/layout/activity_wine.xml b/app/src/main/res/layout/activity_wine.xml
new file mode 100644
index 0000000..8651717
--- /dev/null
+++ b/app/src/main/res/layout/activity_wine.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/adapter_scrollview.xml b/app/src/main/res/layout/adapter_scrollview.xml
new file mode 100644
index 0000000..6952e52
--- /dev/null
+++ b/app/src/main/res/layout/adapter_scrollview.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/header_top_layout.xml b/app/src/main/res/layout/header_top_layout.xml
new file mode 100644
index 0000000..0678507
--- /dev/null
+++ b/app/src/main/res/layout/header_top_layout.xml
@@ -0,0 +1,396 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/layout_emptyview.xml b/app/src/main/res/layout/layout_emptyview.xml
new file mode 100644
index 0000000..6dca32a
--- /dev/null
+++ b/app/src/main/res/layout/layout_emptyview.xml
@@ -0,0 +1,11 @@
+
+
+
diff --git a/app/src/main/res/layout/smiley_headerview.xml b/app/src/main/res/layout/smiley_headerview.xml
new file mode 100644
index 0000000..77753d9
--- /dev/null
+++ b/app/src/main/res/layout/smiley_headerview.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/xrefreshview_car_header.xml b/app/src/main/res/layout/xrefreshview_car_header.xml
new file mode 100755
index 0000000..591aa09
--- /dev/null
+++ b/app/src/main/res/layout/xrefreshview_car_header.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/xrefreshview_jd_header.xml b/app/src/main/res/layout/xrefreshview_jd_header.xml
new file mode 100755
index 0000000..fe7a77d
--- /dev/null
+++ b/app/src/main/res/layout/xrefreshview_jd_header.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/xrefreshview_wine_header.xml b/app/src/main/res/layout/xrefreshview_wine_header.xml
new file mode 100755
index 0000000..c456b83
--- /dev/null
+++ b/app/src/main/res/layout/xrefreshview_wine_header.xml
@@ -0,0 +1,74 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/menu/menu_empty.xml b/app/src/main/res/menu/menu_empty.xml
new file mode 100644
index 0000000..34572bf
--- /dev/null
+++ b/app/src/main/res/menu/menu_empty.xml
@@ -0,0 +1,14 @@
+
diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml
index c38e2ff..ac7abac 100644
--- a/app/src/main/res/values/attrs.xml
+++ b/app/src/main/res/values/attrs.xml
@@ -16,7 +16,16 @@
-->
-
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..2c6f7a2
--- /dev/null
+++ b/app/src/main/res/values/colors.xml
@@ -0,0 +1,20 @@
+
+
+
+ #3F51B5
+ #303F9F
+ #FF4081
+
+ #f5f5f5
+ #bababa
+
+ #19191a
+ #a70e2e
+ #9c9c9c
+ #929292
+ #c0c0c0
+ #616161
+ #29292a
+
+
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 45eba22..fdfa66c 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -5,5 +5,11 @@
Hello world!
恢复数据
点击刷新
+ 切换View
+ 清空或恢复数据
+ 酒杯刷新
+ 京东刷新
+ TaoBaoActivity
+ PluseActivity
diff --git a/build.gradle b/build.gradle
index 60a5b9f..0a8448a 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,11 +1,18 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
+ ext.kotlin_version = '1.3.72'
repositories {
+ google()
+ maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
jcenter()
+ maven { url "https://jitpack.io" }
+ mavenCentral()
+ maven { url 'https://maven.google.com' }
}
dependencies {
- classpath 'com.android.tools.build:gradle:1.3.0'
+ classpath 'com.android.tools.build:gradle:4.0.0'
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
@@ -13,6 +20,11 @@ buildscript {
allprojects {
repositories {
+ google()
+ maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
jcenter()
+ maven { url "https://jitpack.io" }
+ mavenCentral()
+ maven { url 'https://maven.google.com' }
}
}
diff --git a/gif/car_refresh.gif b/gif/car_refresh.gif
new file mode 100644
index 0000000..8ae8e04
Binary files /dev/null and b/gif/car_refresh.gif differ
diff --git a/gif/jd_refresh.gif b/gif/jd_refresh.gif
new file mode 100644
index 0000000..23bc858
Binary files /dev/null and b/gif/jd_refresh.gif differ
diff --git a/gif/wine_refresh.gif b/gif/wine_refresh.gif
new file mode 100644
index 0000000..3bd3718
Binary files /dev/null and b/gif/wine_refresh.gif differ
diff --git a/gif/xrefresh_banner.gif b/gif/xrefresh_banner.gif
new file mode 100644
index 0000000..0617a7d
Binary files /dev/null and b/gif/xrefresh_banner.gif differ
diff --git a/gif/xrefresh_customview.gif b/gif/xrefresh_customview.gif
new file mode 100644
index 0000000..8974a35
Binary files /dev/null and b/gif/xrefresh_customview.gif differ
diff --git a/gif/xrefresh_gridlayout.gif b/gif/xrefresh_gridlayout.gif
new file mode 100644
index 0000000..20f2df2
Binary files /dev/null and b/gif/xrefresh_gridlayout.gif differ
diff --git a/gif/xrefresh_gridview.gif b/gif/xrefresh_gridview.gif
new file mode 100644
index 0000000..287a69f
Binary files /dev/null and b/gif/xrefresh_gridview.gif differ
diff --git a/gif/xrefresh_linearlayout.gif b/gif/xrefresh_linearlayout.gif
new file mode 100644
index 0000000..d615530
Binary files /dev/null and b/gif/xrefresh_linearlayout.gif differ
diff --git a/gif/xrefresh_releasetoloadmore.gif b/gif/xrefresh_releasetoloadmore.gif
new file mode 100644
index 0000000..42c5829
Binary files /dev/null and b/gif/xrefresh_releasetoloadmore.gif differ
diff --git a/gif/xrefresh_smile.gif b/gif/xrefresh_smile.gif
new file mode 100644
index 0000000..5199c99
Binary files /dev/null and b/gif/xrefresh_smile.gif differ
diff --git a/gif/xrefresh_staggeredlayout.gif b/gif/xrefresh_staggeredlayout.gif
new file mode 100644
index 0000000..898b8af
Binary files /dev/null and b/gif/xrefresh_staggeredlayout.gif differ
diff --git a/gradle.properties b/gradle.properties
index 1d3591c..9b7718f 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -15,4 +15,8 @@
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
-# org.gradle.parallel=true
\ No newline at end of file
+# org.gradle.parallel=true
+
+
+android.useAndroidX=true
+android.enableJetifier=true
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 6a0f693..c581025 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Wed Jan 06 21:40:34 CST 2016
+#Sat Jun 13 09:55:16 CST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.2-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
diff --git a/library/build.gradle b/library/build.gradle
index 2001e72..e6eafef 100644
--- a/library/build.gradle
+++ b/library/build.gradle
@@ -1,12 +1,13 @@
apply plugin: 'com.android.library'
+apply plugin: 'kotlin-android'
android {
- compileSdkVersion 23
- buildToolsVersion "23.0.1"
+ compileSdkVersion 29
+ buildToolsVersion "29.0.3"
resourcePrefix "XRefreshView"
defaultConfig {
- minSdkVersion 10
- targetSdkVersion 23
+ minSdkVersion 19
+ targetSdkVersion 29
versionCode 1
versionName "1.0.1"
}
@@ -22,8 +23,10 @@ android {
}
dependencies {
// compile 'com.android.support:recyclerview-v7:23.3.0'
- compile 'com.android.support:recyclerview-v7:23.0.1'
- compile 'com.android.support:support-v4:23.0.1'
+ implementation 'androidx.recyclerview:recyclerview:1.1.0'
+ implementation 'androidx.legacy:legacy-support-v4:1.0.0'
+ implementation "androidx.core:core-ktx:+"
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}
@@ -33,7 +36,10 @@ buildscript {
jcenter()
}
dependencies {
- classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.6'
+ classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4'
}
}
-apply from: 'gradle-jcenter-push.gradle'
\ No newline at end of file
+apply from: 'gradle-jcenter-push.gradle'
+repositories {
+ mavenCentral()
+}
\ No newline at end of file
diff --git a/library/gradle.properties b/library/gradle.properties
index d15ee73..9c1ab82 100644
--- a/library/gradle.properties
+++ b/library/gradle.properties
@@ -1,4 +1,4 @@
-VERSION_NAME=3.2.0
+VERSION_NAME=3.6.9
GROUP=com.huxq17.xrefreshview
POM_NAME=Android universal pull to refresh library
POM_ARTIFACT_ID=xrefreshview
diff --git a/library/src/main/AndroidManifest.xml b/library/src/main/AndroidManifest.xml
index 3a6cf81..e0082bb 100644
--- a/library/src/main/AndroidManifest.xml
+++ b/library/src/main/AndroidManifest.xml
@@ -1,8 +1,3 @@
-
-
-
-
-
+
diff --git a/library/src/main/java/com/andview/refreshview/ScrollRunner.java b/library/src/main/java/com/andview/refreshview/ScrollRunner.java
new file mode 100644
index 0000000..dddc6c8
--- /dev/null
+++ b/library/src/main/java/com/andview/refreshview/ScrollRunner.java
@@ -0,0 +1,9 @@
+package com.andview.refreshview;
+
+/**
+ * Created by huxq17 on 2016/12/15.
+ */
+
+public abstract class ScrollRunner implements Runnable {
+ public boolean isStopLoadMore = false;
+}
diff --git a/library/src/main/java/com/andview/refreshview/XRefreshContentView.java b/library/src/main/java/com/andview/refreshview/XRefreshContentView.java
index 344cc60..d2af78c 100644
--- a/library/src/main/java/com/andview/refreshview/XRefreshContentView.java
+++ b/library/src/main/java/com/andview/refreshview/XRefreshContentView.java
@@ -1,10 +1,11 @@
package com.andview.refreshview;
-import android.support.v4.view.ViewCompat;
-import android.support.v7.widget.GridLayoutManager;
-import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.StaggeredGridLayoutManager;
+import androidx.core.view.ViewCompat;
+import androidx.recyclerview.widget.GridLayoutManager;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.recyclerview.widget.StaggeredGridLayoutManager;
+
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebView;
@@ -14,7 +15,6 @@
import android.widget.ScrollView;
import com.andview.refreshview.XRefreshView.XRefreshViewListener;
-import com.andview.refreshview.XScrollView.OnScrollBottomListener;
import com.andview.refreshview.callback.IFooterCallBack;
import com.andview.refreshview.listener.OnBottomLoadMoreTime;
import com.andview.refreshview.listener.OnTopRefreshTime;
@@ -22,6 +22,7 @@
import com.andview.refreshview.recyclerview.XSpanSizeLookup;
import com.andview.refreshview.utils.LogUtils;
import com.andview.refreshview.utils.Utils;
+import com.andview.refreshview.view.XWebView;
public class XRefreshContentView implements OnScrollListener, OnTopRefreshTime, OnBottomLoadMoreTime {
private View child;
@@ -61,7 +62,7 @@ public void setContentViewLayoutParams(boolean isHeightMatchParent,
lp.height = LayoutParams.MATCH_PARENT;
}
if (isWidthMatchParent) {
- lp.height = LayoutParams.MATCH_PARENT;
+ lp.weight = LayoutParams.MATCH_PARENT;
}
// 默认设置宽高为match_parent
child.setLayoutParams(lp);
@@ -95,15 +96,14 @@ public void scrollToTop() {
absListView.setSelection(0);
} else if (child instanceof RecyclerView) {
RecyclerView recyclerView = (RecyclerView) child;
- RecyclerView.LayoutManager layoutManager = null;
- layoutManager = recyclerView.getLayoutManager();
+ RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
layoutManager.scrollToPosition(0);
}
}
private boolean mSilenceLoadMore = false;
- public void setSlienceLoadMore(boolean silenceLoadMore) {
+ public void setSilenceLoadMore(boolean silenceLoadMore) {
mSilenceLoadMore = silenceLoadMore;
}
@@ -124,18 +124,24 @@ public void setScrollListener() {
private void setScrollViewScrollListener() {
if (child instanceof XScrollView) {
XScrollView scrollView = (XScrollView) child;
- scrollView.registerOnBottomListener(new OnScrollBottomListener() {
-
+ scrollView.setOnScrollListener(mParent, new XScrollView.OnScrollListener() {
@Override
- public void srollToBottom() {
- if (mSilenceLoadMore) {
- if (mRefreshViewListener != null) {
- mRefreshViewListener.onLoadMore(true);
+ public void onScrollStateChanged(ScrollView view, int scrollState, boolean arriveBottom) {
+ if (scrollState == SCROLL_STATE_IDLE && arriveBottom) {
+ if (mSilenceLoadMore) {
+ if (mRefreshViewListener != null) {
+ mRefreshViewListener.onLoadMore(true);
+ }
+ } else if (mContainer != null && !hasLoadCompleted()) {
+ mContainer.invokeLoadMore();
}
- } else if (mContainer != null && !hasLoadCompleted()) {
- mContainer.invokeLoadMore();
}
}
+
+ @Override
+ public void onScroll(int l, int t, int oldl, int oldt) {
+
+ }
});
} else {
throw new RuntimeException("please use XScrollView instead of ScrollView!");
@@ -146,22 +152,24 @@ public void onRecyclerViewScrolled(RecyclerView recyclerView, BaseRecyclerAdapte
if (mRecyclerViewScrollListener != null) {
mRecyclerViewScrollListener.onScrolled(recyclerView, dx, dy);
}
- if (mFooterCallBack == null && !mSilenceLoadMore) {
+ if (mFooterCallBack == null && !mSilenceLoadMore || adapter == null) {
return;
}
RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
getRecyclerViewInfo(layoutManager);
refreshAdapter(adapter, layoutManager);
+ LogUtils.d("test pre onScrolled mIsLoadingMore=" + mIsLoadingMore);
if (onRecyclerViewTop()) {
if (Utils.isRecyclerViewFullscreen(recyclerView)) {
// addFooterView(true);
} else {
- mFooterCallBack.onStateReady();
- mFooterCallBack.callWhenNotAutoLoadMore(mParent);
+ if (mHideFooter) {
+ mFooterCallBack.onStateReady();
+ mFooterCallBack.callWhenNotAutoLoadMore(mParent);
+ }
}
return;
}
- LogUtils.d("test pre onScrolled mIsLoadingMore=" + mIsLoadingMore);
if (dy == 0 && !force) {
return;
}
@@ -187,17 +195,35 @@ public void onRecyclerViewScrolled(RecyclerView recyclerView, BaseRecyclerAdapte
}
}
+ private static final String RECYCLERVIEW_ADAPTER_WARIN = "Recylerview的adapter请继承 BaseRecyclerAdapter,否则不能使用封装的Recyclerview的相关特性";
+
+ private BaseRecyclerAdapter getRecyclerApdater(RecyclerView recyclerView) {
+ BaseRecyclerAdapter adapter = null;
+ if (recyclerView.getAdapter() instanceof BaseRecyclerAdapter) {
+ adapter = (BaseRecyclerAdapter) recyclerView.getAdapter();
+ RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
+ if (layoutManager != null && layoutManager instanceof GridLayoutManager) {
+ GridLayoutManager gridLayoutManager = (GridLayoutManager) layoutManager;
+ gridLayoutManager.setSpanSizeLookup(new XSpanSizeLookup(adapter, gridLayoutManager.getSpanCount()));
+ }
+ adapter.insideEnableFooter(mParent.getPullLoadEnable());
+ initFooterCallBack(adapter, mParent);
+ }
+ return adapter;
+ }
+
+ private BaseRecyclerAdapter mRecyclerApdater;
+
private void setRecyclerViewScrollListener() {
layoutManagerType = null;
final RecyclerView recyclerView = (RecyclerView) child;
- if (recyclerView.getAdapter() == null) {
- return;
- }
- if (!(recyclerView.getAdapter() instanceof BaseRecyclerAdapter)) {
- throw new RuntimeException("Recylerview的adapter请继承 BaseRecyclerAdapter");
+ if (recyclerView.getAdapter() != null) {
+ if (recyclerView.getAdapter() instanceof BaseRecyclerAdapter) {
+ mRecyclerApdater = getRecyclerApdater(recyclerView);
+ } else {
+ LogUtils.w(RECYCLERVIEW_ADAPTER_WARIN);
+ }
}
- final BaseRecyclerAdapter adapter = (BaseRecyclerAdapter) recyclerView.getAdapter();
- adapter.insideEnableFooter(mParent.getPullLoadEnable());
recyclerView.removeOnScrollListener(mOnScrollListener);
mOnScrollListener = new RecyclerView.OnScrollListener() {
@@ -211,20 +237,16 @@ public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
- onRecyclerViewScrolled(recyclerView, adapter, dx, dy, false);
+ if (mRecyclerApdater == null && recyclerView.getAdapter() != null && recyclerView.getAdapter() instanceof BaseRecyclerAdapter) {
+ mRecyclerApdater = getRecyclerApdater(recyclerView);
+ }
+ onRecyclerViewScrolled(recyclerView, mRecyclerApdater, dx, dy, false);
}
};
recyclerView.addOnScrollListener(mOnScrollListener);
-
- RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
- if (layoutManager != null && layoutManager instanceof GridLayoutManager) {
- GridLayoutManager gridLayoutManager = (GridLayoutManager) layoutManager;
- gridLayoutManager.setSpanSizeLookup(new XSpanSizeLookup(adapter, gridLayoutManager.getSpanCount()));
- }
- initFooterCallBack(adapter);
}
- private void initFooterCallBack(BaseRecyclerAdapter adapter) {
+ public void initFooterCallBack(BaseRecyclerAdapter adapter, XRefreshView parent) {
if (!mSilenceLoadMore) {
if (adapter != null) {
View footerView = adapter.getCustomLoadMoreView();
@@ -232,11 +254,10 @@ private void initFooterCallBack(BaseRecyclerAdapter adapter) {
return;
}
mFooterCallBack = (IFooterCallBack) footerView;
- // 如果设置到达底部不自动加载更多,那么就点击footerview加载更多
if (mFooterCallBack != null) {
mFooterCallBack.onStateReady();
- mFooterCallBack.callWhenNotAutoLoadMore(mParent);
- if (mParent != null && !mParent.getPullLoadEnable()) {
+ mFooterCallBack.callWhenNotAutoLoadMore(parent);
+ if (parent != null && !parent.getPullLoadEnable()) {
mFooterCallBack.show(false);
}
}
@@ -285,13 +306,13 @@ public void startLoadMore(boolean silence, BaseRecyclerAdapter adapter, Recycler
return;
}
if (!hasLoadCompleted()) {
- if (mRefreshViewListener != null) {
- mRefreshViewListener.onLoadMore(silence);
- }
mIsLoadingMore = true;
previousTotal = mTotalItemCount;
mFooterCallBack.onStateRefreshing();
setState(XRefreshViewState.STATE_LOADING);
+ if (mRefreshViewListener != null) {
+ mRefreshViewListener.onLoadMore(silence);
+ }
} else {
loadCompleted();
}
@@ -323,7 +344,14 @@ public void releaseToLoadMore(boolean loadmore) {
setState(XRefreshViewState.STATE_RELEASE_TO_LOADMORE);
}
} else {
- doReadyState();
+ if (mHideFooter) {
+ doReadyState();
+ } else {
+ if (mState != XRefreshViewState.STATE_READY) {
+ mFooterCallBack.onStateFinish(false);
+ setState(XRefreshViewState.STATE_READY);
+ }
+ }
}
}
@@ -335,9 +363,11 @@ private void doReadyState() {
}
public void notifyDatasetChanged() {
- final BaseRecyclerAdapter adapter = getRecyclerViewAdapter((RecyclerView) child);
- if (adapter != null) {
- adapter.notifyDataSetChanged();
+ if (isRecyclerView()) {
+ final BaseRecyclerAdapter adapter = getRecyclerViewAdapter((RecyclerView) child);
+ if (adapter != null) {
+ adapter.notifyDataSetChanged();
+ }
}
}
@@ -377,6 +407,7 @@ private void doRecyclerViewloadComplete(boolean hasComplete) {
if (mFooterCallBack == null || !isFooterEnable()) return;
final RecyclerView recyclerView = (RecyclerView) child;
if (hasComplete) {
+ mHideFooter = true;
mFooterCallBack.onStateFinish(true);
if (!Utils.isRecyclerViewFullscreen(recyclerView)) {
child.postDelayed(new Runnable() {
@@ -416,7 +447,7 @@ private BaseRecyclerAdapter getRecyclerViewAdapter(RecyclerView recyclerView) {
if (adapter instanceof BaseRecyclerAdapter) {
return (BaseRecyclerAdapter) adapter;
} else {
- throw new RuntimeException("Recylerview的adapter请继承 BaseRecyclerAdapter");
+ LogUtils.w(RECYCLERVIEW_ADAPTER_WARIN);
}
}
return null;
@@ -547,7 +578,9 @@ public void loadCompleted() {
@Override
public void run() {
resetLayout();
- addFooterView(false);
+ if (mHasLoadComplete) {
+ addFooterView(false);
+ }
}
}, mPinnedTime);
}
@@ -612,6 +645,7 @@ public void run() {
*
* @param enablePullLoad
*/
+
public void setEnablePullLoad(boolean enablePullLoad) {
addFooterView(enablePullLoad);
hasIntercepted = false;
@@ -687,8 +721,21 @@ public void setOnBottomLoadMoreTime(OnBottomLoadMoreTime bottomLoadMoreTime) {
this.mBottomLoadMoreTime = bottomLoadMoreTime;
}
+ private boolean isForbidLoadMore = true;
+
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
+ /******解决abslistview数据不满一屏的时候,会重复加载更多的问题 start ******/
+ if (mParent.isStopLoadMore() && scrollState == OnScrollListener.SCROLL_STATE_FLING) {
+ isForbidLoadMore = true;
+ }
+ if (isForbidLoadMore) {
+ if (!mParent.isStopLoadMore() && scrollState == OnScrollListener.SCROLL_STATE_IDLE) {
+ isForbidLoadMore = false;
+ }
+ return;
+ }
+ /******解决abslistview数据不满一屏的时候,会重复加载更多的问题 end ******/
if (mSilenceLoadMore) {
if (mRefreshViewListener != null && !hasLoadCompleted() && !mIsLoadingMore && mTotalItemCount - 1 <= view.getLastVisiblePosition() + mPreLoadCount) {
mRefreshViewListener.onLoadMore(true);
@@ -767,15 +814,19 @@ public boolean canChildPullUp() {
|| absListView.getLastVisiblePosition() != mTotalItemCount - 1;
} else if (child instanceof WebView) {
WebView webview = (WebView) child;
- return canScrollVertically(child, 1)
- || webview.getContentHeight() * webview.getScale() != webview.getHeight() + webview.getScrollY();
+ if (webview instanceof XWebView) {
+ return !((XWebView) webview).isBottom();
+ } else {
+ float left = webview.getContentHeight() * webview.getScale();
+ int right = webview.getHeight() + webview.getScrollY();
+ return left != right;
+ }
} else if (child instanceof ScrollView) {
ScrollView scrollView = (ScrollView) child;
View childView = scrollView.getChildAt(0);
if (childView != null) {
return canScrollVertically(child, 1)
- || scrollView.getScrollY() != childView.getHeight()
- - scrollView.getHeight();
+ || scrollView.getScrollY() < childView.getHeight() - scrollView.getHeight();
}
} else {
return canScrollVertically(child, 1);
@@ -802,6 +853,10 @@ public boolean isRecyclerView() {
if (mSilenceLoadMore) {
return false;
} else if (null != child && child instanceof RecyclerView) {
+ final RecyclerView recyclerView = (RecyclerView) child;
+ if (recyclerView.getAdapter() != null && !(recyclerView.getAdapter() instanceof BaseRecyclerAdapter)) {
+ return false;
+ }
return true;
}
return false;
diff --git a/library/src/main/java/com/andview/refreshview/XRefreshHolder.java b/library/src/main/java/com/andview/refreshview/XRefreshHolder.java
index 9797c4a..e76b8e9 100644
--- a/library/src/main/java/com/andview/refreshview/XRefreshHolder.java
+++ b/library/src/main/java/com/andview/refreshview/XRefreshHolder.java
@@ -17,6 +17,5 @@ public boolean hasFooterPullUp() {
}
public boolean isOverHeader(int deltaY){
return mOffsetY<-deltaY;
-
}
}
diff --git a/library/src/main/java/com/andview/refreshview/XRefreshView.java b/library/src/main/java/com/andview/refreshview/XRefreshView.java
index a971cf6..f7415cb 100644
--- a/library/src/main/java/com/andview/refreshview/XRefreshView.java
+++ b/library/src/main/java/com/andview/refreshview/XRefreshView.java
@@ -5,15 +5,19 @@
import android.content.res.TypedArray;
import android.os.Build;
import android.os.Build.VERSION_CODES;
-import android.os.Handler;
-import android.support.v4.view.ViewCompat;
-import android.support.v7.widget.RecyclerView;
+
+import androidx.annotation.LayoutRes;
+import androidx.core.view.ViewCompat;
+import androidx.recyclerview.widget.RecyclerView;
+
import android.util.AttributeSet;
+import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.animation.LinearInterpolator;
+import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.LinearLayout;
import android.widget.Scroller;
@@ -26,6 +30,7 @@
import com.andview.refreshview.utils.Utils;
import java.util.Calendar;
+import java.util.concurrent.CopyOnWriteArrayList;
public class XRefreshView extends LinearLayout {
// -- header view
@@ -80,8 +85,7 @@ public class XRefreshView extends LinearLayout {
/**
* 当刷新完成以后,headerview和footerview被固定的时间,在这个时间以后headerview才会回弹
*/
- private int mPinnedTime;
- private static Handler mHandler = new Handler();
+ private int mPinnedTime = 1000;
private XRefreshViewState mState = null;
/**
* 当已无更多数据时候,需把这个变量设为true
@@ -100,6 +104,31 @@ public class XRefreshView extends LinearLayout {
* 当Recyclerview加载完成的时候,不允许界面被上拉
*/
private boolean enablePullUp = true;
+ /**
+ * 布局是否准备好了,准备好以后才能进行自动刷新这种操作
+ */
+ private boolean mLayoutReady = false;
+ private boolean mNeedToRefresh = false;
+
+ private float headerTopHeight;
+
+ public float getHeaderTopHeight() {
+ return headerTopHeight;
+ }
+
+ public void setHeaderTopHeight(float headerTopHeight) {
+ this.headerTopHeight = headerTopHeight;
+ }
+
+ private boolean isAddHeaderTop = false;
+
+ public boolean isAddHeaderTop() {
+ return isAddHeaderTop;
+ }
+
+ public void setAddHeaderTop(boolean addHeaderTop) {
+ isAddHeaderTop = addHeaderTop;
+ }
public XRefreshView(Context context) {
this(context, null);
@@ -151,11 +180,26 @@ public void setMoveForHorizontal(boolean isForHorizontalMove) {
/**
* 设置静默加载更多,旨在提供被刷新的view滚动到底部的监听,自动静默加载更多
*/
+ @Deprecated
public void setSilenceLoadMore() {
- mContentView.setSlienceLoadMore(true);
+ mContentView.setSilenceLoadMore(true);
setPullLoadEnable(false);
}
+ /**
+ * 设置静默加载更多,旨在提供被刷新的view滚动到底部的监听,自动静默加载更多
+ *
+ * @param enable 是否启用静默加载模式
+ */
+ public void setSilenceLoadMore(boolean enable) {
+ if (enable) {
+ mContentView.setSilenceLoadMore(true);
+ setPullLoadEnable(false);
+ } else {
+ mContentView.setSilenceLoadMore(false);
+ }
+ }
+
/**
* 当切换layoutManager时,需调用此方法
*/
@@ -165,11 +209,9 @@ public void notifyLayoutManagerChanged() {
}
private void initWithContext(Context context, AttributeSet attrs) {
-
// 根据属性设置参数
if (attrs != null) {
TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
-
R.styleable.XRefreshView, 0, 0);
try {
isHeightMatchParent = a.getBoolean(
@@ -186,53 +228,76 @@ private void initWithContext(Context context, AttributeSet attrs) {
a.recycle();
}
}
- mHeaderView = new XRefreshViewHeader(context);
- mFooterView = new XRefreshViewFooter(context);
+ addHeaderView();
this.getViewTreeObserver().addOnGlobalLayoutListener(
new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
- addHeaderView();
- addFooterView(this);
+ mLayoutReady = true;
+ if (autoRefresh || mNeedToRefresh) {
+ startRefresh();
+ }
+ setHeadMoveLargestDistence(mHeadMoveDistence);
+ attachContentView();
+ addFooterView();
+ if (waitForShowEmptyView == 1) {
+ enableEmptyView(true);
+ waitForShowEmptyView = 0;
+ }
+ // 移除视图树监听器
+ removeViewTreeObserver(this);
}
});
mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
}
private void addHeaderView() {
- Utils.removeViewFromParent(mHeaderView);
- addView(mHeaderView, 0);
- mHeaderView.measure(0, 0);
+ if (mHeaderView == null) {
+ mHeaderView = new XRefreshViewHeader(getContext());
+ }
+ dealAddHeaderView();
+ }
+
+ private void dealAddHeaderView() {
+ if (indexOfChild(mHeaderView) == -1) {
+ Utils.removeViewFromParent(mHeaderView);
+ addView(mHeaderView, 0);
+ mHeaderCallBack = (IHeaderCallBack) mHeaderView;
+ setRefreshTime();
+ checkPullRefreshEnable();
+ }
+ }
+
+ private void dealAddFooterView() {
+ if (indexOfChild(mFooterView) == -1) {
+ if (needAddFooterView()) {
+ Utils.removeViewFromParent(mFooterView);
+ try {
+ addView(mFooterView, 2);
+ } catch (IndexOutOfBoundsException e) {
+ new RuntimeException("XRefreshView is allowed to have one and only one child");
+ }
+ }
+ mFooterCallBack = (IFooterCallBack) mFooterView;
+ checkPullLoadEnable();
+ }
+ }
+
+ private void attachContentView() {
mContentView.setContentView(XRefreshView.this.getChildAt(1));
mContentView.setContainer(autoLoadMore ? this : null);
mContentView.setContentViewLayoutParams(isHeightMatchParent, isWidthMatchParent);
- mHeaderCallBack = (IHeaderCallBack) mHeaderView;
- mFooterCallBack = (IFooterCallBack) mFooterView;
- setRefreshTime();
- checkPullRefreshEnable();
- checkPullLoadEnable();
- }
-
- private void addFooterView(OnGlobalLayoutListener listener) {
- mHeaderViewHeight = ((IHeaderCallBack) mHeaderView).getHeaderHeight();
mContentView.setHolder(mHolder);
mContentView.setParent(this);
mContentView.setScrollListener();
- if (needAddFooterView()) {
- LogUtils.d("test add footView" + ";mHeaderViewHeight=" + mHeaderViewHeight);
- Utils.removeViewFromParent(mFooterView);
- addView(mFooterView);
- }
- // 移除视图树监听器
- removeViewTreeObserver(listener);
- if (autoRefresh) {
- startRefresh();
- }
- if (mHeadMoveDistence == 0) {
- int ScreenHeight = Utils.getScreenSize(getContext()).y;
- mHeadMoveDistence = ScreenHeight / 3;
+ }
+
+ private void addFooterView() {
+ if (mFooterView == null) {
+ mFooterView = new XRefreshViewFooter(getContext());
}
+ dealAddFooterView();
}
@SuppressWarnings("deprecation")
@@ -245,31 +310,52 @@ public void removeViewTreeObserver(OnGlobalLayoutListener listener) {
}
}
+ private int mHeaderGap;
+
+ public void setHeaderGap(int headerGap) {
+ mHeaderGap = headerGap;
+ }
+
+ private void getHeaderHeight() {
+ if (mHeaderCallBack != null) {
+ mHeaderViewHeight = mHeaderCallBack.getHeaderHeight();
+ }
+ }
+
+ private void getFooterHeight() {
+ if (mFooterCallBack != null) {
+ mFootHeight = mFooterCallBack.getFooterHeight();
+ }
+// if (mFooterView != null) {
+// mFootHeight = mFooterView.getMeasuredHeight();
+// }
+ }
+
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
-// int width2 = getDefaultSize(0, widthMeasureSpec);
-// int height2 = getDefaultSize(0, heightMeasureSpec);
int childCount = getChildCount();
int finalHeight = 0;
+ final int paddingLeft = getPaddingLeft();
+ final int paddingRight = getPaddingRight();
+ final int paddingTop = getPaddingTop();
+ final int paddingBottom = getPaddingBottom();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
- if (child.getVisibility() != View.GONE) {
- final int paddingLeft = getPaddingLeft();
- final int paddingRight = getPaddingRight();
- final int paddingTop = getPaddingTop();
- final int paddingBottom = getPaddingBottom();
- LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) child.getLayoutParams();
- int childWidthSpec = getChildMeasureSpec(widthMeasureSpec,
- paddingLeft + paddingRight + lp.leftMargin + lp.rightMargin, lp.width);
- int childHeightSpec = getChildMeasureSpec(heightMeasureSpec,
- paddingTop + paddingBottom + lp.topMargin + lp.bottomMargin, lp.height);
- child.measure(childWidthSpec, childHeightSpec);
- finalHeight += child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;
- }
+ LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) child.getLayoutParams();
+ int childWidthSpec = MeasureSpec.makeMeasureSpec(width - lp.leftMargin - lp.rightMargin - paddingLeft - paddingRight, MeasureSpec.EXACTLY);
+// int childWidthSpec = getChildMeasureSpec(widthMeasureSpec,
+// paddingLeft + paddingRight, getMeasuredWidth()-lp.leftMargin - lp.rightMargin);
+ int childHeightSpec = getChildMeasureSpec(heightMeasureSpec,
+ paddingTop + paddingBottom + lp.topMargin + lp.bottomMargin, lp.height);
+ child.measure(childWidthSpec, childHeightSpec);
+ finalHeight += child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;
}
- setMeasuredDimension(width, finalHeight);
+ setMeasuredDimension(width, height);
+ hideUselessFooter();
+ getHeaderHeight();
+ getFooterHeight();
}
@Override
@@ -277,7 +363,6 @@ protected void onLayout(boolean changed, int l, int t2, int r, int b) {
// super.onLayout(changed, l, t2, r, b);
// if(mHolder.mOffsetY!=0)return;
LogUtils.d("onLayout mHolder.mOffsetY=" + mHolder.mOffsetY);
- mFootHeight = ((IFooterCallBack) mFooterView).getFooterHeight();
int childCount = getChildCount();
int top = getPaddingTop() + mHolder.mOffsetY;
int adHeight = 0;
@@ -294,7 +379,6 @@ protected void onLayout(boolean changed, int l, int t2, int r, int b) {
if (child.getVisibility() != View.GONE) {
if (i == 0) {
adHeight = child.getMeasuredHeight() - mHeaderViewHeight;
- // 通过把headerview向上移动一个headerview高度的距离来达到隐藏headerview的效果
child.layout(l, top - mHeaderViewHeight, l + r, top + adHeight);
top += adHeight;
} else if (i == 1) {
@@ -303,22 +387,62 @@ protected void onLayout(boolean changed, int l, int t2, int r, int b) {
child.layout(l, top, l + r, bottom);
top += childHeight + bottomMargin;
} else {
- int bottom = child.getMeasuredHeight() + top;
- child.layout(l, top, l + r, bottom);
- top += child.getMeasuredHeight();
+ if (needAddFooterView()) {
+ int bottom = child.getMeasuredHeight() + top;
+ child.layout(l, top, l + r, bottom);
+ top += child.getMeasuredHeight();
+ } else {
+ hideUselessFooter();
+ }
}
}
}
}
+ private void hideUselessFooter() {
+ if (!needAddFooterView() && mFooterView != null && mFooterView.getVisibility() != GONE) {
+ mFooterView.setVisibility(GONE);
+ }
+ }
+
private boolean isIntercepted = false;
private int mHeadMoveDistence;
+ private final CopyOnWriteArrayList mTouchLifeCycles = new CopyOnWriteArrayList<>();
+
+ interface TouchLifeCycle {
+
+ void onTouch(MotionEvent event);
+ }
+
+
+ public void addTouchLifeCycle(TouchLifeCycle lifeCycle) {
+ mTouchLifeCycles.add(lifeCycle);
+ }
+
+ public void removeTouchLifeCycle(TouchLifeCycle lifeCycle) {
+ if (lifeCycle == null) {
+ return;
+ }
+ if (mTouchLifeCycles.contains(lifeCycle)) {
+ mTouchLifeCycles.remove(lifeCycle);
+ }
+ }
+
+ private void updateTouchAction(MotionEvent event) {
+ for (TouchLifeCycle lifeCycle : mTouchLifeCycles) {
+ if (lifeCycle != null) {
+ lifeCycle.onTouch(event);
+ }
+ }
+ }
+
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
final int action = ev.getAction();
int deltaY = 0;
int deltaX = 0;
+ updateTouchAction(ev);
switch (action) {
case MotionEvent.ACTION_DOWN:
mHasSendCancelEvent = false;
@@ -365,7 +489,7 @@ public boolean dispatchTouchEvent(MotionEvent ev) {
} else {
return super.dispatchTouchEvent(ev);
}
- if (!mPullLoading && !mReleaseToLoadMore && mContentView.isTop() && (deltaY > 0 || (deltaY < 0 && mHolder.hasHeaderPullDown()))) {
+ if (!mPullLoading && !mReleaseToLoadMore && mContentView.isTop() && ((deltaY > 0 && !mHolder.hasFooterPullUp()) || (deltaY < 0 && mHolder.hasHeaderPullDown()))) {
sendCancelEvent();
updateHeaderHeight(currentY, deltaY);
} else if (!mPullRefreshing && mContentView.isBottom()
@@ -388,18 +512,19 @@ public boolean dispatchTouchEvent(MotionEvent ev) {
// mRefreshViewListener.onRelease(mHolder.mOffsetY);
// }
if (mHolder.hasHeaderPullDown()) {
- if (mEnablePullRefresh && !mStopingRefresh && !mPullRefreshing && mHolder.mOffsetY > mHeaderViewHeight) {
+ if (mEnablePullRefresh && !mStopingRefresh && !mPullRefreshing && mHolder.mOffsetY > (isAddHeaderTop ? (mHeaderViewHeight - headerTopHeight) : mHeaderViewHeight)) {
mPullRefreshing = true;
mHeaderCallBack.onStateRefreshing();
mState = XRefreshViewState.STATE_REFRESHING;
if (mRefreshViewListener != null) {
mRefreshViewListener.onRefresh();
+ mRefreshViewListener.onRefresh(true);
}
}
resetHeaderHeight();
} else if (mHolder.hasFooterPullUp()) {
if (!mStopingRefresh) {
- if (mEnablePullLoad && needAddFooterView() && !mHasLoadComplete) {
+ if (mEnablePullLoad && !isEmptyViewShowing() && needAddFooterView() && !mHasLoadComplete) {
invokeLoadMore();
} else {
int offset = 0 - mHolder.mOffsetY;
@@ -412,14 +537,17 @@ public boolean dispatchTouchEvent(MotionEvent ev) {
mInitialMotionY = 0;
isIntercepted = false;
mMoveForHorizontal = false;
- mIsIntercept = false;
break;
}
return super.dispatchTouchEvent(ev);
}
+ public XRefreshContentView getContentView() {
+ return mContentView;
+ }
+
public boolean invokeLoadMore() {
- if (mEnablePullLoad && !mPullRefreshing && !mStopingRefresh && !mHasLoadComplete) {
+ if (mEnablePullLoad && !isEmptyViewShowing() && !mPullRefreshing && !mStopingRefresh && !mHasLoadComplete) {
int offset = 0 - mHolder.mOffsetY - mFootHeight;
if (offset != 0) {
startScroll(offset, Utils.computeScrollVerticalDuration(offset, getHeight()));
@@ -468,7 +596,13 @@ private void sendCancelEvent() {
* @param headMoveDistence
*/
public void setHeadMoveLargestDistence(int headMoveDistence) {
- mHeadMoveDistence = headMoveDistence;
+ if (headMoveDistence <= 0) {
+ int ScreenHeight = Utils.getScreenSize(getContext()).y;
+ mHeadMoveDistence = ScreenHeight / 3;
+ } else {
+ mHeadMoveDistence = headMoveDistence;
+ }
+ mHeadMoveDistence = mHeadMoveDistence <= mHeaderViewHeight ? mHeaderViewHeight + 1 : mHeadMoveDistence;
}
private void sendDownEvent() {
@@ -625,9 +759,15 @@ private void releaseToLoadMore(boolean loadMore) {
private void updateFooterHeight(int deltaY) {
if (mEnablePullLoad) {
if (needAddFooterView()) {
- if (mState != XRefreshViewState.STATE_LOADING) {
- mFooterCallBack.onStateRefreshing();
- mState = XRefreshViewState.STATE_LOADING;
+ if (isEmptyViewShowing()) {
+ if (mFooterCallBack.isShowing()) {
+ mFooterCallBack.show(false);
+ }
+ } else {
+ if (mState != XRefreshViewState.STATE_LOADING) {
+ mFooterCallBack.onStateRefreshing();
+ mState = XRefreshViewState.STATE_LOADING;
+ }
}
} else if (canReleaseToLoadMore()) {
releaseToLoadMore(mHolder.mOffsetY != 0);
@@ -673,21 +813,20 @@ public void setAutoLoadMore(boolean autoLoadMore) {
}
public void startRefresh() {
- if (!mEnablePullRefresh || mHolder.mOffsetY != 0 || mContentView.isLoading() || !isEnabled()) {
+ if (!mEnablePullRefresh || mHolder.mOffsetY != 0 || mContentView.isLoading() || mPullRefreshing || !isEnabled()) {
return;
}
- // 如果条件成立,代表布局还没有初始化完成,改变标记,等待该方法再次调用,完成开始刷新
- if (mHeaderCallBack == null) {
- this.autoRefresh = true;
- } else {
- if (!mPullRefreshing) {
- updateHeaderHeight(0, mHeaderViewHeight, 0);
- mPullRefreshing = true;
- if (mRefreshViewListener != null) {
- mRefreshViewListener.onRefresh();
- }
- mContentView.scrollToTop();
+ if (mLayoutReady) {
+ mNeedToRefresh = false;
+ updateHeaderHeight(0, mHeaderViewHeight, 0);
+ mPullRefreshing = true;
+ if (mRefreshViewListener != null) {
+ mRefreshViewListener.onRefresh();
+ mRefreshViewListener.onRefresh(false);
}
+ mContentView.scrollToTop();
+ } else {
+ mNeedToRefresh = true;
}
}
@@ -696,15 +835,13 @@ public void startRefresh() {
*/
private void resetHeaderHeight() {
float height = mHolder.mOffsetY;
- if (height == 0) // not visible.
- return;
// refreshing and header isn't shown fully. do nothing.
- if (mPullRefreshing && height <= mHeaderViewHeight) {
+ if (mPullRefreshing && (height <= (isAddHeaderTop ? (mHeaderViewHeight - headerTopHeight) : mHeaderViewHeight) || height == 0)) {
return;
}
- int offsetY = 0;
+ int offsetY;
if (mPullRefreshing) {
- offsetY = mHeaderViewHeight - mHolder.mOffsetY;
+ offsetY = (int) ((isAddHeaderTop ? (mHeaderViewHeight - headerTopHeight) : mHeaderViewHeight) - mHolder.mOffsetY);
startScroll(offsetY, Utils.computeScrollVerticalDuration(offsetY, getHeight()));
} else {
offsetY = 0 - mHolder.mOffsetY;
@@ -721,42 +858,11 @@ public void moveView(int deltaY) {
mFooterView.offsetTopAndBottom(deltaY);
}
ViewCompat.postInvalidateOnAnimation(this);
-
- if (mRefreshViewListener != null
- && (mContentView.isTop() || mPullRefreshing)) {
- double offset = 1.0 * mHolder.mOffsetY / mHeaderViewHeight;
- offset = offset > 1 ? 1 : offset;
- mRefreshViewListener.onHeaderMove(offset, mHolder.mOffsetY);
- mHeaderCallBack.onHeaderMove(offset, mHolder.mOffsetY, deltaY);
- }
- }
-
- @Override
- public void computeScroll() {
- super.computeScroll();
- if (mScroller.computeScrollOffset()) {
- int lastScrollY = mHolder.mOffsetY;
- int currentY = mScroller.getCurrY();
- int offsetY = currentY - lastScrollY;
- lastScrollY = currentY;
- moveView(offsetY);
-
- LogUtils.d("currentY=" + currentY + ";mHolder.mOffsetY=" + mHolder.mOffsetY);
- if (enableReleaseToLoadMore && mHolder.mOffsetY == 0 && mReleaseToLoadMore && mContentView != null && mContentView.isBottom()) {
- mReleaseToLoadMore = false;
- mContentView.startLoadMore(false, null, null);
- }
- } else {
- int currentY = mScroller.getCurrY();
- if (mHolder.mOffsetY == 0) {
- enablePullUp(true);
- mStopingRefresh = false;
- } else {
- //有时scroller已经停止了,但是却没有回到应该在的位置,执行下面的方法恢复
- if (mStopingRefresh && !mPullLoading && !mPullRefreshing) {
- startScroll(-currentY, Utils.computeScrollVerticalDuration(currentY, getHeight()));
- }
- }
+ if (mRefreshViewListener != null && (mContentView.isTop() || mPullRefreshing)) {
+ double headerMovePercent = 1.0 * mHolder.mOffsetY / mHeaderViewHeight;
+// headerMovePercent = headerMovePercent > 1 ? 1 : headerMovePercent;
+ mRefreshViewListener.onHeaderMove(headerMovePercent, mHolder.mOffsetY);
+ mHeaderCallBack.onHeaderMove(headerMovePercent, mHolder.mOffsetY, deltaY);
}
}
@@ -766,12 +872,19 @@ public void computeScroll() {
* stop refresh, reset header view.
*/
public void stopRefresh() {
+ stopRefresh(true);
+ }
+
+ /**
+ * stop refresh, reset header view.
+ */
+ public void stopRefresh(boolean success) {
LogUtils.d("stopRefresh mPullRefreshing=" + mPullRefreshing);
if (mPullRefreshing == true) {
mStopingRefresh = true;
- mHeaderCallBack.onStateFinish();
+ mHeaderCallBack.onStateFinish(success);
mState = XRefreshViewState.STATE_COMPLETE;
- mHandler.postDelayed(new Runnable() {
+ postDelayed(new Runnable() {
@Override
public void run() {
@@ -819,25 +932,7 @@ private void setRefreshTime() {
* stop load more, reset footer view.
*/
public void stopLoadMore() {
- if (needAddFooterView()) {
- if (mPullLoading == true) {
- mStopingRefresh = true;
- mState = XRefreshViewState.STATE_COMPLETE;
- mFooterCallBack.onStateFinish(true);
- if (mPinnedTime >= 1000) {// 在加载更多完成以后,只有mPinnedTime大于1s才生效,不然效果不好
- mHandler.postDelayed(new Runnable() {
-
- @Override
- public void run() {
- endLoadMore(true);
- }
- }, mPinnedTime);
- } else {
- endLoadMore(true);
- }
- }
- }
- mContentView.stopLoading(true);
+ stopLoadMore(true);
}
/**
@@ -845,31 +940,48 @@ public void run() {
*
* @param hideFooter hide footerview if true
*/
- public void stopLoadMore(final boolean hideFooter) {
+ public void stopLoadMore(boolean hideFooter) {
+ mState = XRefreshViewState.STATE_FINISHED;
+ stopLoadMore(hideFooter, SCROLLBACK_DURATION);
+ }
+
+ private void stopLoadMore(final boolean hideFooter, final int scrollBackDuration) {
if (needAddFooterView()) {
- if (mPullLoading == true) {
+ if (mPullLoading) {
mStopingRefresh = true;
- mState = XRefreshViewState.STATE_COMPLETE;
- mFooterCallBack.onStateFinish(hideFooter);
+ if (mState == XRefreshViewState.STATE_COMPLETE) {
+ mFooterCallBack.onStateComplete();
+ } else {
+ mFooterCallBack.onStateFinish(hideFooter);
+ }
if (mPinnedTime >= 1000) {// 在加载更多完成以后,只有mPinnedTime大于1s才生效,不然效果不好
- mHandler.postDelayed(new Runnable() {
+ postDelayed(new Runnable() {
@Override
public void run() {
- endLoadMore(hideFooter);
+ endLoadMore(hideFooter, scrollBackDuration);
}
}, mPinnedTime);
} else {
- endLoadMore(hideFooter);
+ endLoadMore(hideFooter, scrollBackDuration);
}
}
}
+
mContentView.stopLoading(hideFooter);
}
+ private void scrollback(int offset) {
+ View child = mContentView.getContentView();
+ if (child instanceof AbsListView) {
+ AbsListView absListView = (AbsListView) child;
+ absListView.smoothScrollBy(offset, 0);
+ }
+ }
+
protected void resetLayout() {
enablePullUp(false);
- if (mHolder.mOffsetY != 0) {
+ if (mHolder.mOffsetY != 0 && !mStopingRefresh) {
startScroll(-mHolder.mOffsetY, Utils.computeScrollVerticalDuration(mHolder.mOffsetY, getHeight()));
}
}
@@ -879,14 +991,19 @@ protected void enablePullUp(boolean enablePullUp) {
}
/**
- * 此方法当没有更多数据时调用,不要与stopLoadMore()同时调用,内部已经调用了stopLoadMore()。
+ * 此方法当没有更多数据时调用,不要和stopLoadMore()同时调用
*
* @param hasComplete
*/
public void setLoadComplete(boolean hasComplete) {
mHasLoadComplete = hasComplete;
if (needAddFooterView()) {
- stopLoadMore();
+ if (hasComplete) {
+ mState = XRefreshViewState.STATE_COMPLETE;
+ } else {
+ mState = XRefreshViewState.STATE_NORMAL;
+ }
+ stopLoadMore(true, SCROLLBACK_DURATION);
if (!hasComplete && mEnablePullLoad && mFooterCallBack != null) {
mFooterCallBack.onStateRefreshing();
// mFooterCallBack.show(true);
@@ -899,9 +1016,21 @@ public boolean hasLoadCompleted() {
return mHasLoadComplete;
}
- private void endLoadMore(boolean hideFooter) {
+ private int SCROLLBACK_DURATION = 300;
+
+ /**
+ * 设置当非RecyclerView上拉加载完成以后的回弹时间
+ *
+ * @param duration
+ */
+ public void setScrollBackDuration(int duration) {
+ SCROLLBACK_DURATION = duration;
+ }
+
+ private void endLoadMore(boolean hideFooter, int scrolbackduration) {
mPullLoading = false;
- startScroll(-mHolder.mOffsetY, 0);
+ mRunnable.isStopLoadMore = true;
+ startScroll(-mHolder.mOffsetY, scrolbackduration);
// mFooterCallBack.onStateRefreshing();
if (mHasLoadComplete && hideFooter) {
mFooterCallBack.show(false);
@@ -913,12 +1042,51 @@ private void endLoadMore(boolean hideFooter) {
* @param duration 滑动持续时间
*/
public void startScroll(int offsetY, int duration) {
- if (offsetY != 0) {
- mScroller.startScroll(0, mHolder.mOffsetY, 0, offsetY, duration);
- ViewCompat.postInvalidateOnAnimation(this);
- }
+ mScroller.startScroll(0, mHolder.mOffsetY, 0, offsetY, duration);
+ post(mRunnable);
}
+ public boolean isStopLoadMore() {
+ return mRunnable.isStopLoadMore;
+ }
+
+ private ScrollRunner mRunnable = new ScrollRunner() {
+
+ @Override
+ public void run() {
+ if (mScroller.computeScrollOffset()) {
+ int lastScrollY = mHolder.mOffsetY;
+ int currentY = mScroller.getCurrY();
+ int offsetY = currentY - lastScrollY;
+ lastScrollY = currentY;
+ moveView(offsetY);
+ int[] location = new int[2];
+ mHeaderView.getLocationInWindow(location);
+ LogUtils.d("currentY=" + currentY + ";mHolder.mOffsetY=" + mHolder.mOffsetY);
+ if (enableReleaseToLoadMore && mHolder.mOffsetY == 0 && mReleaseToLoadMore && mContentView != null && mContentView.isBottom()) {
+ mReleaseToLoadMore = false;
+ mContentView.startLoadMore(false, null, null);
+ }
+ post(this);
+ if (isStopLoadMore) {
+ scrollback(offsetY);
+ }
+ } else {
+ int currentY = mScroller.getCurrY();
+ if (mHolder.mOffsetY == 0) {
+ enablePullUp(true);
+ mStopingRefresh = false;
+ isStopLoadMore = false;
+ } else {
+ //有时scroller已经停止了,但是却没有回到应该在的位置,执行下面的方法恢复
+ if (mStopingRefresh && !mPullLoading && !mPullRefreshing) {
+ startScroll(-currentY, Utils.computeScrollVerticalDuration(currentY, getHeight()));
+ }
+ }
+ }
+ }
+ };
+
/**
* 设置Abslistview的滚动监听事件
*
@@ -928,6 +1096,73 @@ public void setOnAbsListViewScrollListener(OnScrollListener scrollListener) {
mContentView.setOnAbsListViewScrollListener(scrollListener);
}
+ private View mEmptyView;
+ private View mTempTarget;
+
+ public void setEmptyView(View emptyView) {
+ Utils.removeViewFromParent(emptyView);
+ mEmptyView = emptyView;
+ addEmptyViewLayoutParams();
+ }
+
+ private void addEmptyViewLayoutParams() {
+ if (mEmptyView == null) {
+ return;
+ }
+ LayoutParams layoutparams = generateDefaultLayoutParams();
+ layoutparams.height = LayoutParams.MATCH_PARENT;
+ layoutparams.width = LayoutParams.MATCH_PARENT;
+ mEmptyView.setLayoutParams(layoutparams);
+
+ }
+
+ public void setEmptyView(@LayoutRes int emptyView) {
+ String resourceTypeName = getContext().getResources().getResourceTypeName(emptyView);
+ if (!resourceTypeName.contains("layout")) {
+ throw new RuntimeException(getContext().getResources().getResourceName(emptyView) + " is a illegal layoutid , please check your layout id first !");
+ }
+ setEmptyView(LayoutInflater.from(getContext()).inflate(emptyView, this, false));
+ }
+
+ private int waitForShowEmptyView = 0;
+
+ public void enableEmptyView(boolean enable) {
+ if (!mLayoutReady) {
+ waitForShowEmptyView = enable ? 1 : 2;
+ return;
+ }
+ View contentView = getChildAt(1);
+ if (enable) {
+ if (mEmptyView != null && contentView != mEmptyView) {
+ mTempTarget = getChildAt(1);
+ swapContentView(mEmptyView);
+ }
+ } else {
+ if (mTempTarget != null && contentView == mEmptyView) {
+ swapContentView(mTempTarget);
+ }
+ }
+ }
+
+ public boolean isEmptyViewShowing() {
+ if (mEmptyView != null && getChildCount() >= 2) {
+ View child = getChildAt(1);
+ return child == mEmptyView;
+ }
+ return false;
+ }
+
+ public View getEmptyView() {
+ return mEmptyView;
+ }
+
+ private void swapContentView(View newContentView) {
+ removeViewAt(1);
+ addView(newContentView, 1);
+ mContentView.setContentView(newContentView);
+ mContentView.scrollToTop();
+ }
+
/**
* 设置Recylerview的滚动监听事件
*/
@@ -998,7 +1233,7 @@ public void setPinnedTime(int pinnedTime) {
}
/**
- * 设置是否在数据加载完成以后隐藏footerview
+ * 设置Recyclerview是否在数据加载完成以后隐藏footerview
*
* @param hide true则隐藏footerview,false则反之,默认隐藏
*/
@@ -1022,14 +1257,16 @@ public void setPinnedContent(boolean isPinned) {
*/
public void setCustomHeaderView(View headerView) {
if (headerView instanceof IHeaderCallBack) {
+ if (mHeaderView != null) {
+ removeView(mHeaderView);
+ }
mHeaderView = headerView;
+ dealAddHeaderView();
} else {
- throw new RuntimeException(
- "headerView must be implementes IHeaderCallBack!");
+ throw new RuntimeException("headerView must be implementes IHeaderCallBack!");
}
}
-
/**
* 设置自定义footerView
*
@@ -1037,7 +1274,11 @@ public void setCustomHeaderView(View headerView) {
*/
public void setCustomFooterView(View footerView) {
if (footerView instanceof IFooterCallBack) {
+ if (mFooterView != null) {
+ removeView(mFooterView);
+ }
mFooterView = footerView;
+ dealAddFooterView();
} else {
throw new RuntimeException(
"footerView must be implementes IFooterCallBack!");
@@ -1048,36 +1289,51 @@ public void setCustomFooterView(View footerView) {
* implements this interface to get refresh/load more event.
*/
public interface XRefreshViewListener {
- public void onRefresh();
+ /**
+ * use {@link #onRefresh(boolean)} instead.
+ */
+ @Deprecated
+ void onRefresh();
+
+ /**
+ * @param isPullDown 是不是由下拉手势引起的刷新,是则返回true,反之则是自动刷新或者是调用{@link #startRefresh()}引起的刷新
+ */
+ void onRefresh(boolean isPullDown);
/**
* @param isSilence 是不是静默加载,静默加载即不显示footerview,自动监听滚动到底部并触发此回调
*/
- public void onLoadMore(boolean isSilence);
+ void onLoadMore(boolean isSilence);
/**
* 用户手指释放的监听回调
*
* @param direction >0: 下拉释放,<0:上拉释放 注:暂时没有使用这个方法
*/
- public void onRelease(float direction);
+ void onRelease(float direction);
/**
* 获取headerview显示的高度与headerview高度的比例
*
- * @param offset 移动距离和headerview高度的比例,范围是0~1,0:headerview完全没显示
- * 1:headerview完全显示
- * @param offsetY headerview移动的距离
+ * @param headerMovePercent 移动距离和headerview高度的比例
+ * @param offsetY headerview移动的距离
*/
- public void onHeaderMove(double offset, int offsetY);
+ void onHeaderMove(double headerMovePercent, int offsetY);
}
public static class SimpleXRefreshListener implements XRefreshViewListener {
-
+ /**
+ * use {@link #onRefresh(boolean)} instead.
+ */
+ @Deprecated
@Override
public void onRefresh() {
}
+ @Override
+ public void onRefresh(boolean isPullDown) {
+ }
+
@Override
public void onLoadMore(boolean isSilence) {
}
diff --git a/library/src/main/java/com/andview/refreshview/XRefreshViewHeader.java b/library/src/main/java/com/andview/refreshview/XRefreshViewHeader.java
index 976c75d..af1cbc2 100644
--- a/library/src/main/java/com/andview/refreshview/XRefreshViewHeader.java
+++ b/library/src/main/java/com/andview/refreshview/XRefreshViewHeader.java
@@ -19,133 +19,133 @@
import java.util.Calendar;
public class XRefreshViewHeader extends LinearLayout implements IHeaderCallBack {
- private ViewGroup mContent;
- private ImageView mArrowImageView;
- private ImageView mOkImageView;
- private ProgressBar mProgressBar;
- private TextView mHintTextView;
- private TextView mHeaderTimeTextView;
- private Animation mRotateUpAnim;
- private Animation mRotateDownAnim;
- private final int ROTATE_ANIM_DURATION = 180;
-
- public XRefreshViewHeader(Context context) {
- super(context);
- initView(context);
- }
-
- /**
- * @param context
- * @param attrs
- */
- public XRefreshViewHeader(Context context, AttributeSet attrs) {
- super(context, attrs);
- initView(context);
- }
-
- private void initView(Context context) {
- mContent = (ViewGroup) LayoutInflater.from(context).inflate(
- R.layout.xrefreshview_header, this);
- mArrowImageView = (ImageView) findViewById(R.id.xrefreshview_header_arrow);
- mOkImageView = (ImageView) findViewById(R.id.xrefreshview_header_ok);
- mHintTextView = (TextView) findViewById(R.id.xrefreshview_header_hint_textview);
- mHeaderTimeTextView = (TextView) findViewById(R.id.xrefreshview_header_time);
- mProgressBar = (ProgressBar) findViewById(R.id.xrefreshview_header_progressbar);
-
- mRotateUpAnim = new RotateAnimation(0.0f, -180.0f,
- Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,0.5f);
- mRotateUpAnim.setDuration(ROTATE_ANIM_DURATION);
- mRotateUpAnim.setFillAfter(true);
- mRotateDownAnim = new RotateAnimation(-180.0f, 0.0f,
- Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
- 0.5f);
- mRotateDownAnim.setDuration(ROTATE_ANIM_DURATION);
- mRotateDownAnim.setFillAfter(true);
- }
-
- public void setRefreshTime(long lastRefreshTime) {
- // 获取当前时间
- Calendar mCalendar = Calendar.getInstance();
- long refreshTime = mCalendar.getTimeInMillis();
- long howLong = refreshTime - lastRefreshTime;
- int minutes = (int) (howLong / 1000 / 60);
- String refreshTimeText = null;
- Resources resources = getContext().getResources();
- if (minutes < 1) {
- refreshTimeText = resources
- .getString(R.string.xrefreshview_refresh_justnow);
- } else if (minutes < 60) {
- refreshTimeText = resources
- .getString(R.string.xrefreshview_refresh_minutes_ago);
- refreshTimeText = Utils.format(refreshTimeText, minutes);
- } else if (minutes < 60 * 24) {
- refreshTimeText = resources
- .getString(R.string.xrefreshview_refresh_hours_ago);
- refreshTimeText = Utils.format(refreshTimeText, minutes / 60);
- } else {
- refreshTimeText = resources
- .getString(R.string.xrefreshview_refresh_days_ago);
- refreshTimeText = Utils.format(refreshTimeText, minutes / 60 / 24);
- }
- mHeaderTimeTextView.setText(refreshTimeText);
- }
-
- /**
- * hide footer when disable pull load more
- */
- public void hide() {
- setVisibility(View.GONE);
- }
-
- public void show() {
- setVisibility(View.VISIBLE);
- }
-
- @Override
- public void onStateNormal() {
- mProgressBar.setVisibility(View.GONE);
- mArrowImageView.setVisibility(View.VISIBLE);
- mOkImageView.setVisibility(View.GONE);
- mArrowImageView.startAnimation(mRotateDownAnim);
- mHintTextView.setText(R.string.xrefreshview_header_hint_normal);
- }
-
- @Override
- public void onStateReady() {
- mProgressBar.setVisibility(View.GONE);
- mOkImageView.setVisibility(View.GONE);
- mArrowImageView.setVisibility(View.VISIBLE);
- mArrowImageView.clearAnimation();
- mArrowImageView.startAnimation(mRotateUpAnim);
- mHintTextView.setText(R.string.xrefreshview_header_hint_ready);
- mHeaderTimeTextView.setVisibility(View.VISIBLE);
- }
-
- @Override
- public void onStateRefreshing() {
- mArrowImageView.clearAnimation();
- mArrowImageView.setVisibility(View.GONE);
- mOkImageView.setVisibility(View.GONE);
- mProgressBar.setVisibility(View.VISIBLE);
- mHintTextView.setText(R.string.xrefreshview_header_hint_loading);
- }
-
- @Override
- public void onStateFinish() {
- mArrowImageView.setVisibility(View.GONE);
- mOkImageView.setVisibility(View.VISIBLE);
- mProgressBar.setVisibility(View.GONE);
- mHintTextView.setText(R.string.xrefreshview_header_hint_loaded);
- mHeaderTimeTextView.setVisibility(View.GONE);
- }
-
- @Override
- public void onHeaderMove(double offset,int offsetY,int deltaY) {
-
- }
-
- @Override
- public int getHeaderHeight() {
- return getMeasuredHeight();
- }
+ private ViewGroup mContent;
+ private ImageView mArrowImageView;
+ private ImageView mOkImageView;
+ private ProgressBar mProgressBar;
+ private TextView mHintTextView;
+ private TextView mHeaderTimeTextView;
+ private Animation mRotateUpAnim;
+ private Animation mRotateDownAnim;
+ private final int ROTATE_ANIM_DURATION = 180;
+
+ public XRefreshViewHeader(Context context) {
+ super(context);
+ initView(context);
+ }
+
+ /**
+ * @param context
+ * @param attrs
+ */
+ public XRefreshViewHeader(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ initView(context);
+ }
+
+ private void initView(Context context) {
+ mContent = (ViewGroup) LayoutInflater.from(context).inflate(
+ R.layout.xrefreshview_header, this);
+ mArrowImageView = (ImageView) findViewById(R.id.xrefreshview_header_arrow);
+ mOkImageView = (ImageView) findViewById(R.id.xrefreshview_header_ok);
+ mHintTextView = (TextView) findViewById(R.id.xrefreshview_header_hint_textview);
+ mHeaderTimeTextView = (TextView) findViewById(R.id.xrefreshview_header_time);
+ mProgressBar = (ProgressBar) findViewById(R.id.xrefreshview_header_progressbar);
+
+ mRotateUpAnim = new RotateAnimation(0.0f, -180.0f,
+ Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
+ mRotateUpAnim.setDuration(ROTATE_ANIM_DURATION);
+ mRotateUpAnim.setFillAfter(true);
+ mRotateDownAnim = new RotateAnimation(-180.0f, 0.0f,
+ Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
+ 0.5f);
+ mRotateDownAnim.setDuration(0);
+ mRotateDownAnim.setFillAfter(true);
+ }
+
+ public void setRefreshTime(long lastRefreshTime) {
+ // 获取当前时间
+ Calendar mCalendar = Calendar.getInstance();
+ long refreshTime = mCalendar.getTimeInMillis();
+ long howLong = refreshTime - lastRefreshTime;
+ int minutes = (int) (howLong / 1000 / 60);
+ String refreshTimeText = null;
+ Resources resources = getContext().getResources();
+ if (minutes < 1) {
+ refreshTimeText = resources
+ .getString(R.string.xrefreshview_refresh_justnow);
+ } else if (minutes < 60) {
+ refreshTimeText = resources
+ .getString(R.string.xrefreshview_refresh_minutes_ago);
+ refreshTimeText = Utils.format(refreshTimeText, minutes);
+ } else if (minutes < 60 * 24) {
+ refreshTimeText = resources
+ .getString(R.string.xrefreshview_refresh_hours_ago);
+ refreshTimeText = Utils.format(refreshTimeText, minutes / 60);
+ } else {
+ refreshTimeText = resources
+ .getString(R.string.xrefreshview_refresh_days_ago);
+ refreshTimeText = Utils.format(refreshTimeText, minutes / 60 / 24);
+ }
+ mHeaderTimeTextView.setText(refreshTimeText);
+ }
+
+ /**
+ * hide footer when disable pull refresh
+ */
+ public void hide() {
+ setVisibility(View.GONE);
+ }
+
+ public void show() {
+ setVisibility(View.VISIBLE);
+ }
+
+ @Override
+ public void onStateNormal() {
+ mProgressBar.setVisibility(View.GONE);
+ mArrowImageView.setVisibility(View.VISIBLE);
+ mOkImageView.setVisibility(View.GONE);
+ mArrowImageView.startAnimation(mRotateDownAnim);
+ mHintTextView.setText(R.string.xrefreshview_header_hint_normal);
+ }
+
+ @Override
+ public void onStateReady() {
+ mProgressBar.setVisibility(View.GONE);
+ mOkImageView.setVisibility(View.GONE);
+ mArrowImageView.setVisibility(View.VISIBLE);
+ mArrowImageView.clearAnimation();
+ mArrowImageView.startAnimation(mRotateUpAnim);
+ mHintTextView.setText(R.string.xrefreshview_header_hint_ready);
+ mHeaderTimeTextView.setVisibility(View.VISIBLE);
+ }
+
+ @Override
+ public void onStateRefreshing() {
+ mArrowImageView.clearAnimation();
+ mArrowImageView.setVisibility(View.GONE);
+ mOkImageView.setVisibility(View.GONE);
+ mProgressBar.setVisibility(View.VISIBLE);
+ mHintTextView.setText(R.string.xrefreshview_header_hint_loading);
+ }
+
+ @Override
+ public void onStateFinish(boolean success) {
+ mArrowImageView.setVisibility(View.GONE);
+ mOkImageView.setVisibility(View.VISIBLE);
+ mProgressBar.setVisibility(View.GONE);
+ mHintTextView.setText(success ? R.string.xrefreshview_header_hint_loaded : R.string.xrefreshview_header_hint_loaded_fail);
+ mHeaderTimeTextView.setVisibility(View.GONE);
+ }
+
+ @Override
+ public void onHeaderMove(double headerMovePercent, int offsetY, int deltaY) {
+
+ }
+
+ @Override
+ public int getHeaderHeight() {
+ return getMeasuredHeight();
+ }
}
diff --git a/library/src/main/java/com/andview/refreshview/XScrollView.java b/library/src/main/java/com/andview/refreshview/XScrollView.java
index 26c4684..a33fda1 100644
--- a/library/src/main/java/com/andview/refreshview/XScrollView.java
+++ b/library/src/main/java/com/andview/refreshview/XScrollView.java
@@ -2,41 +2,157 @@
import android.content.Context;
import android.util.AttributeSet;
-import android.view.View;
+import android.view.MotionEvent;
+import android.view.ViewConfiguration;
import android.widget.ScrollView;
public class XScrollView extends ScrollView {
- private OnScrollBottomListener _listener;
- private int _calCount;
-
- public interface OnScrollBottomListener {
- void srollToBottom();
- }
-
- public void registerOnBottomListener(OnScrollBottomListener l) {
- _listener = l;
- }
-
- public void unRegisterOnBottomListener() {
- _listener = null;
- }
-
- public XScrollView(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- @Override
- protected void onScrollChanged(int l, int t, int oldl, int oldt) {
- View view = this.getChildAt(0);
- if (this.getHeight() + this.getScrollY() == view.getHeight()) {
- _calCount++;
- if (_calCount == 1) {
- if (_listener != null) {
- _listener.srollToBottom();
- }
- }
- } else {
- _calCount = 0;
- }
- }
+
+ private OnScrollListener onScrollListener, mScrollListener;
+ // 是否在触摸状态
+ private boolean inTouch = false;
+ // 上次滑动的最后位置
+ private int lastT = 0;
+ private XRefreshView mParent;
+ private int mTouchSlop;
+ private float lastY;
+
+ public XScrollView(Context context) {
+ super(context, null);
+ }
+
+ public XScrollView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
+ }
+
+ @Override
+ protected void onScrollChanged(int l, int t, int oldl, int oldt) {
+ super.onScrollChanged(l, t, oldl, oldt);
+ if (onScrollListener == null) {
+ return;
+ }
+ if (inTouch) {
+ if (t != oldt) {
+ // 有手指触摸,并且位置有滚动
+ onScrollListener.onScrollStateChanged(this, OnScrollListener.SCROLL_STATE_TOUCH_SCROLL, isBottom());
+ if (mScrollListener != null) {
+ mScrollListener.onScrollStateChanged(this, OnScrollListener.SCROLL_STATE_TOUCH_SCROLL, isBottom());
+ }
+ }
+ } else {
+ if (t != oldt) {
+ // 没有手指触摸,并且位置有滚动,就可以简单的认为是在fling
+ onScrollListener.onScrollStateChanged(this, OnScrollListener.SCROLL_STATE_FLING, isBottom());
+ if (mScrollListener != null) {
+ mScrollListener.onScrollStateChanged(this, OnScrollListener.SCROLL_STATE_FLING, isBottom());
+ }
+ // 记住上次滑动的最后位置
+ lastT = t;
+ removeCallbacks(mRunnable);
+ postDelayed(mRunnable, 20);
+ }
+ }
+ onScrollListener.onScroll(l, t, oldl, oldt);
+ if (mScrollListener != null) {
+ mScrollListener.onScroll(l, t, oldl, oldt);
+ }
+ }
+
+ private Runnable mRunnable = new Runnable() {
+ @Override
+ public void run() {
+ if (lastT == getScrollY() && !inTouch) {
+ // 如果上次的位置和当前的位置相同,可认为是在空闲状态
+ onScrollListener.onScrollStateChanged(XScrollView.this, OnScrollListener.SCROLL_STATE_IDLE, isBottom());
+ if (mScrollListener != null) {
+ mScrollListener.onScrollStateChanged(XScrollView.this, OnScrollListener.SCROLL_STATE_IDLE, isBottom());
+ }
+ }
+ }
+ };
+
+ private boolean isBottom() {
+ return getScrollY() + getHeight() >= computeVerticalScrollRange();
+ }
+
+ protected void setOnScrollListener(XRefreshView parent, OnScrollListener scrollListener) {
+ mParent = parent;
+ this.onScrollListener = scrollListener;
+ mParent.addTouchLifeCycle(new XRefreshView.TouchLifeCycle() {
+ @Override
+ public void onTouch(MotionEvent event) {
+ int action = event.getAction();
+ switch (action) {
+ case MotionEvent.ACTION_DOWN:
+ lastY = event.getRawY();
+ case MotionEvent.ACTION_MOVE:
+ inTouch = true;
+ break;
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_CANCEL:
+ inTouch = false;
+ lastT = getScrollY();
+ float curY = event.getRawY();
+ if (lastY - curY >= mTouchSlop) {
+ removeCallbacks(mRunnable);
+ postDelayed(mRunnable, 20);
+ }
+ break;
+ }
+ }
+ });
+ }
+
+ /**
+ * 设置XScrollView的滚动监听
+ *
+ * @param scrollListener
+ */
+ public void setOnScrollListener(OnScrollListener scrollListener) {
+ mScrollListener = scrollListener;
+ }
+
+ /**
+ * 滚动监听事件
+ */
+ public interface OnScrollListener {
+ /**
+ * The view is not scrolling. Note navigating the list using the
+ * trackball counts as being in the idle state since these transitions
+ * are not animated.
+ */
+ int SCROLL_STATE_IDLE = 0;
+
+ /**
+ * The user is scrolling using touch, and their finger is still on the
+ * screen
+ */
+ int SCROLL_STATE_TOUCH_SCROLL = 1;
+
+ /**
+ * The user had previously been scrolling using touch and had performed
+ * a fling. The animation is now coasting to a stop
+ */
+ int SCROLL_STATE_FLING = 2;
+
+ /**
+ * 滑动状态回调
+ *
+ * @param view 当前的scrollView
+ * @param scrollState 当前的状态
+ * @param arriveBottom 是否到达底部
+ */
+ void onScrollStateChanged(ScrollView view, int scrollState, boolean arriveBottom);
+
+ /**
+ * 滑动位置回调
+ *
+ * @param l
+ * @param t
+ * @param oldl
+ * @param oldt
+ */
+ void onScroll(int l, int t, int oldl, int oldt);
+ }
}
diff --git a/library/src/main/java/com/andview/refreshview/XWebView.java b/library/src/main/java/com/andview/refreshview/XWebView.java
deleted file mode 100644
index aa2fd53..0000000
--- a/library/src/main/java/com/andview/refreshview/XWebView.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package com.andview.refreshview;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.webkit.WebView;
-
-public class XWebView extends WebView {
- private OnScrollBottomListener _listener;
- private int _calCount;
-
- public interface OnScrollBottomListener {
- void srollToBottom();
- }
-
- public void registerOnBottomListener(OnScrollBottomListener l) {
- _listener = l;
- }
-
- public void unRegisterOnBottomListener() {
- _listener = null;
- }
-
- public XWebView(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- @Override
- protected void onScrollChanged(int l, int t, int oldl, int oldt) {
- if (this.getHeight() + this.getScrollY() == getHeight()) {
- _calCount++;
- if (_calCount == 1) {
- if (_listener != null) {
- _listener.srollToBottom();
- }
- }
- } else {
- _calCount = 0;
- }
- }
-}
diff --git a/library/src/main/java/com/andview/refreshview/callback/IFooterCallBack.java b/library/src/main/java/com/andview/refreshview/callback/IFooterCallBack.kt
similarity index 62%
rename from library/src/main/java/com/andview/refreshview/callback/IFooterCallBack.java
rename to library/src/main/java/com/andview/refreshview/callback/IFooterCallBack.kt
index 9fd53e9..fd38e95 100644
--- a/library/src/main/java/com/andview/refreshview/callback/IFooterCallBack.java
+++ b/library/src/main/java/com/andview/refreshview/callback/IFooterCallBack.kt
@@ -1,61 +1,60 @@
-package com.andview.refreshview.callback;
+package com.andview.refreshview.callback
-import com.andview.refreshview.XRefreshView;
+import com.andview.refreshview.XRefreshView
-public interface IFooterCallBack {
+interface IFooterCallBack {
/**
* 当不是到达底部自动加载更多的时候,需要自己写点击事件
*
* @param xRefreshView
*/
- void callWhenNotAutoLoadMore(XRefreshView xRefreshView);
+ fun callWhenNotAutoLoadMore(xRefreshView: XRefreshView?)
/**
* 正常状态,例如需要点击footerview才能加载更多,主要是到达底部不自动加载更多时会被调用
*/
- void onStateReady();
+ fun onStateReady()
/**
* 正在刷新
*/
- void onStateRefreshing();
+ fun onStateRefreshing()
/**
* 当footerview被上拉时,松开手指即可加载更多
*/
- void onReleaseToLoadMore();
+ fun onReleaseToLoadMore()
/**
* 刷新结束 在此方法中不要调用show()方法
*
- * @param hidefooter footerview是否被隐藏
+ * @param hidefooter footerview是否被隐藏,hideFooter参数由XRefreshView.stopLoadMore(boolean)传入
*/
- void onStateFinish(boolean hidefooter);
+ fun onStateFinish(hidefooter: Boolean)
/**
* 已无更多数据 在此方法中不要调用show()方法
*/
- void onStateComplete();
-
+ fun onStateComplete()
/**
* 设置显示或者隐藏footerview 不要在onStateFinish和onStateComplete中调用此方法
*
* @param show
*/
- void show(boolean show);
+ fun show(show: Boolean)
/**
* footerview是否显示中
*
* @return
*/
- boolean isShowing();
+ val isShowing: Boolean
/**
* 获得footerview的高度
*
* @return
*/
- int getFooterHeight();
-}
+ val footerHeight: Int
+}
\ No newline at end of file
diff --git a/library/src/main/java/com/andview/refreshview/callback/IHeaderCallBack.java b/library/src/main/java/com/andview/refreshview/callback/IHeaderCallBack.java
deleted file mode 100644
index 6c20758..0000000
--- a/library/src/main/java/com/andview/refreshview/callback/IHeaderCallBack.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package com.andview.refreshview.callback;
-
-/**
- * 提供自定义headerview的接口
- *
- * @author huxq17@163.com
- *
- */
-public interface IHeaderCallBack {
- /**
- * 正常状态
- */
- public void onStateNormal();
-
- /**
- * 准备刷新
- */
- public void onStateReady();
-
- /**
- * 正在刷新
- */
- public void onStateRefreshing();
-
- /**
- * 刷新结束
- */
- public void onStateFinish();
-
- /**
- * 获取headerview显示的高度与headerview高度的比例
- *
- * @param offset
- * 移动距离和headerview高度的比例,范围是0~1,0:headerview完全没显示 1:headerview完全显示
- * @param offsetY
- * headerview移动的距离
- */
- public void onHeaderMove(double offset, int offsetY,int deltaY);
-
- /**
- * 设置显示上一次刷新的时间
- *
- * @param lastRefreshTime
- * 上一次刷新的时间
- */
- public void setRefreshTime(long lastRefreshTime);
-
- /**
- * 隐藏footerview
- */
- public void hide();
-
- /**
- * 显示footerview
- */
- public void show();
-
- /**
- * 获得headerview的高度,如果不想headerview全部被隐藏,就可以只返回一部分的高度
- *
- * @return
- */
- public int getHeaderHeight();
-}
\ No newline at end of file
diff --git a/library/src/main/java/com/andview/refreshview/callback/IHeaderCallBack.kt b/library/src/main/java/com/andview/refreshview/callback/IHeaderCallBack.kt
new file mode 100644
index 0000000..5e03b52
--- /dev/null
+++ b/library/src/main/java/com/andview/refreshview/callback/IHeaderCallBack.kt
@@ -0,0 +1,62 @@
+package com.andview.refreshview.callback
+
+/**
+ * 提供自定义headerview的接口
+ *
+ * @author huxq17@163.com
+ */
+interface IHeaderCallBack {
+ /**
+ * 正常状态
+ */
+ fun onStateNormal()
+
+ /**
+ * 准备刷新
+ */
+ fun onStateReady()
+
+ /**
+ * 正在刷新
+ */
+ fun onStateRefreshing()
+
+ /**
+ * 刷新结束
+ *
+ * @param success 是否刷新成功 success参数由XRefreshView.stopRefresh(boolean)传入
+ */
+ fun onStateFinish(success: Boolean)
+
+ /**
+ * 获取headerview显示的高度与headerview高度的比例
+ *
+ * @param headerMovePercent 移动距离和headerview高度的比例
+ * @param offsetY headerview移动的距离
+ */
+ fun onHeaderMove(headerMovePercent: Double, offsetY: Int, deltaY: Int)
+
+ /**
+ * 设置显示上一次刷新的时间
+ *
+ * @param lastRefreshTime 上一次刷新的时间
+ */
+ fun setRefreshTime(lastRefreshTime: Long)
+
+ /**
+ * 隐藏footerview
+ */
+ fun hide()
+
+ /**
+ * 显示footerview
+ */
+ fun show()
+
+ /**
+ * 获得headerview的高度,如果不想headerview全部被隐藏,就可以只返回一部分的高度
+ *
+ * @return
+ */
+ val headerHeight: Int
+}
\ No newline at end of file
diff --git a/library/src/main/java/com/andview/refreshview/listener/OnBottomLoadMoreTime.java b/library/src/main/java/com/andview/refreshview/listener/OnBottomLoadMoreTime.java
deleted file mode 100644
index 8788131..0000000
--- a/library/src/main/java/com/andview/refreshview/listener/OnBottomLoadMoreTime.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.andview.refreshview.listener;
-/**
- * 上拉加载更多的时机
- * @author huxq17@163.com
- *
- */
-public interface OnBottomLoadMoreTime {
- public boolean isBottom();
-}
diff --git a/library/src/main/java/com/andview/refreshview/listener/OnBottomLoadMoreTime.kt b/library/src/main/java/com/andview/refreshview/listener/OnBottomLoadMoreTime.kt
new file mode 100644
index 0000000..10c8ea3
--- /dev/null
+++ b/library/src/main/java/com/andview/refreshview/listener/OnBottomLoadMoreTime.kt
@@ -0,0 +1,9 @@
+package com.andview.refreshview.listener
+
+/**
+ * 上拉加载更多的时机
+ * @author huxq17@163.com
+ */
+interface OnBottomLoadMoreTime {
+ val isBottom: Boolean
+}
\ No newline at end of file
diff --git a/library/src/main/java/com/andview/refreshview/listener/OnTopRefreshTime.java b/library/src/main/java/com/andview/refreshview/listener/OnTopRefreshTime.java
deleted file mode 100644
index 5becfe5..0000000
--- a/library/src/main/java/com/andview/refreshview/listener/OnTopRefreshTime.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.andview.refreshview.listener;
-/**
- * 下拉刷新更多的时机
- * @author huxq17@163.com
- *
- */
-public interface OnTopRefreshTime {
- public boolean isTop();
-}
diff --git a/library/src/main/java/com/andview/refreshview/listener/OnTopRefreshTime.kt b/library/src/main/java/com/andview/refreshview/listener/OnTopRefreshTime.kt
new file mode 100644
index 0000000..6a8f9db
--- /dev/null
+++ b/library/src/main/java/com/andview/refreshview/listener/OnTopRefreshTime.kt
@@ -0,0 +1,9 @@
+package com.andview.refreshview.listener
+
+/**
+ * 下拉刷新更多的时机
+ * @author huxq17@163.com
+ */
+interface OnTopRefreshTime {
+ val isTop: Boolean
+}
\ No newline at end of file
diff --git a/library/src/main/java/com/andview/refreshview/recyclerview/BaseRecyclerAdapter.java b/library/src/main/java/com/andview/refreshview/recyclerview/BaseRecyclerAdapter.java
index be4f79f..f8a8f1a 100644
--- a/library/src/main/java/com/andview/refreshview/recyclerview/BaseRecyclerAdapter.java
+++ b/library/src/main/java/com/andview/refreshview/recyclerview/BaseRecyclerAdapter.java
@@ -1,14 +1,17 @@
package com.andview.refreshview.recyclerview;
import android.content.Context;
-import android.support.annotation.LayoutRes;
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewParent;
import android.widget.FrameLayout;
+import androidx.annotation.LayoutRes;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.recyclerview.widget.StaggeredGridLayoutManager;
+
+import com.andview.refreshview.XRefreshView;
import com.andview.refreshview.callback.IFooterCallBack;
import com.andview.refreshview.utils.LogUtils;
import com.andview.refreshview.utils.Utils;
@@ -82,6 +85,16 @@ public void removeFooterView() {
public abstract VH getViewHolder(View view);
+ /**
+ * 会调用此方法来判断是否显示空布局,返回true就会显示空布局
+ * 如有特殊需要,可重写此方法
+ *
+ * @return
+ */
+ public boolean isEmpty() {
+ return getAdapterItemCount() == 0;
+ }
+
/**
* @param parent
* @param viewType
@@ -112,18 +125,26 @@ public void onViewAttachedToWindow(VH holder) {
ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();
if (lp != null && lp instanceof StaggeredGridLayoutManager.LayoutParams) {
StaggeredGridLayoutManager.LayoutParams p = (StaggeredGridLayoutManager.LayoutParams) lp;
- p.setFullSpan(isFooter(position));
+ p.setFullSpan(isFooter(position) || isHeader(position));
}
}
+ private final RecyclerViewDataObserver observer = new RecyclerViewDataObserver();
+
+ private XRefreshView mParent;
+
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
-// RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
-// if (manager instanceof GridLayoutManager) {
-// final GridLayoutManager gridManager = ((GridLayoutManager) manager);
-// gridManager.setSpanSizeLookup(new XSpanSizeLookup(this, ((GridLayoutManager) manager).getSpanCount()));
-// }
+ ViewParent parent = recyclerView.getParent();
+ if (parent != null && parent instanceof XRefreshView) {
+ mParent = (XRefreshView) recyclerView.getParent();
+ if (mParent != null && !observer.hasAttached()) {
+ observer.setData(this, mParent);
+ observer.attach();
+ registerAdapterDataObserver(observer);
+ }
+ }
}
/**
@@ -132,9 +153,12 @@ public void onAttachedToRecyclerView(RecyclerView recyclerView) {
* @param footerView the inflated view
*/
public void setCustomLoadMoreView(View footerView) {
- Utils.removeViewFromParent(customLoadMoreView);
if (footerView instanceof IFooterCallBack) {
customLoadMoreView = footerView;
+ Utils.removeViewFromParent(customLoadMoreView);
+ if (mParent != null && mParent.getContentView() != null) {
+ mParent.getContentView().initFooterCallBack(this, mParent);
+ }
showFooter(customLoadMoreView, false);
notifyDataSetChanged();
} else {
@@ -144,13 +168,12 @@ public void setCustomLoadMoreView(View footerView) {
public void setHeaderView(View headerView, RecyclerView recyclerView) {
if (recyclerView == null) return;
- Utils.removeViewFromParent(customLoadMoreView);
+ Utils.removeViewFromParent(headerView);
customHeaderView = headerView;
notifyDataSetChanged();
}
public View setHeaderView(@LayoutRes int id, RecyclerView recyclerView) {
-
if (recyclerView == null) return null;
Context context = recyclerView.getContext();
String resourceTypeName = context.getResources().getResourceTypeName(id);
@@ -240,6 +263,7 @@ public void insideEnableFooter(boolean enable) {
isFooterEnable = enable;
}
+
/**
* Insert a item to the list of the adapter
*
@@ -272,7 +296,7 @@ public void remove(List> list, int position) {
*/
public void clear(List> list) {
int start = getStart();
- int size = list.size() + start;
+ int size = list.size();
list.clear();
notifyItemRangeRemoved(start, size);
}
diff --git a/library/src/main/java/com/andview/refreshview/recyclerview/RecyclerViewDataObserver.java b/library/src/main/java/com/andview/refreshview/recyclerview/RecyclerViewDataObserver.java
new file mode 100644
index 0000000..eeedbbc
--- /dev/null
+++ b/library/src/main/java/com/andview/refreshview/recyclerview/RecyclerViewDataObserver.java
@@ -0,0 +1,84 @@
+package com.andview.refreshview.recyclerview;
+
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.andview.refreshview.XRefreshView;
+
+/**
+ * Created by 2144 on 2016/8/16.
+ */
+public class RecyclerViewDataObserver extends RecyclerView.AdapterDataObserver {
+ private BaseRecyclerAdapter mAdapter;
+ private XRefreshView xRefreshView;
+ private boolean mAttached;
+ private boolean hasData = true;
+
+ public RecyclerViewDataObserver() {
+
+ }
+
+ public void setData(BaseRecyclerAdapter adapter, XRefreshView xRefreshView) {
+ mAdapter = adapter;
+ this.xRefreshView = xRefreshView;
+// onChanged();
+ }
+
+ private void enableEmptyView(boolean enable) {
+ if (xRefreshView != null) {
+ xRefreshView.enableEmptyView(enable);
+ }
+ }
+
+ @Override
+ public void onChanged() {
+ if (mAdapter == null) {
+ return;
+ }
+ if (mAdapter.isEmpty()) {
+ if (hasData) {
+ enableEmptyView(true);
+ hasData = false;
+ }
+ } else {
+ if (!hasData) {
+ enableEmptyView(false);
+ hasData = true;
+ }
+ }
+ }
+
+ @Override
+ public void onItemRangeChanged(int positionStart, int itemCount, Object payload) {
+ onChanged();
+ }
+
+ @Override
+ public void onItemRangeChanged(int positionStart, int itemCount) {
+ onChanged();
+ }
+
+ @Override
+ public void onItemRangeInserted(int positionStart, int itemCount) {
+ onChanged();
+ }
+
+ @Override
+ public void onItemRangeRemoved(int positionStart, int itemCount) {
+ onChanged();
+ }
+
+ @Override
+ public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
+ onChanged();
+ }
+
+
+ public void attach() {
+ mAttached = true;
+ }
+
+ public boolean hasAttached() {
+ return mAttached;
+ }
+}
diff --git a/library/src/main/java/com/andview/refreshview/recyclerview/XSpanSizeLookup.java b/library/src/main/java/com/andview/refreshview/recyclerview/XSpanSizeLookup.java
index 57ee25a..a46cea5 100644
--- a/library/src/main/java/com/andview/refreshview/recyclerview/XSpanSizeLookup.java
+++ b/library/src/main/java/com/andview/refreshview/recyclerview/XSpanSizeLookup.java
@@ -1,6 +1,7 @@
package com.andview.refreshview.recyclerview;
-import android.support.v7.widget.GridLayoutManager;
+
+import androidx.recyclerview.widget.GridLayoutManager;
/**
* use this class to let the footerview have full width
diff --git a/library/src/main/java/com/andview/refreshview/utils/LogUtils.java b/library/src/main/java/com/andview/refreshview/utils/LogUtils.java
index 9a8ee7d..5a889a2 100644
--- a/library/src/main/java/com/andview/refreshview/utils/LogUtils.java
+++ b/library/src/main/java/com/andview/refreshview/utils/LogUtils.java
@@ -19,6 +19,19 @@ public class LogUtils {
private LogUtils() {
}
+ /**
+ * 是否打印log
+ *
+ * @param enable
+ */
+ public static void enableLog(boolean enable) {
+ allowD = enable;
+ allowE = enable;
+ allowI = enable;
+ allowV = enable;
+ allowW = enable;
+ }
+
public static boolean allowD = true;
public static boolean allowE = true;
public static boolean allowI = true;
@@ -235,6 +248,7 @@ public static void wtf(Throwable tr) {
Log.wtf(tag, tr);
}
}
+
public static StackTraceElement getCallerStackTraceElement() {
return Thread.currentThread().getStackTrace()[4];
}
diff --git a/library/src/main/java/com/andview/refreshview/utils/Utils.java b/library/src/main/java/com/andview/refreshview/utils/Utils.java
index a89ca1d..d3803f2 100644
--- a/library/src/main/java/com/andview/refreshview/utils/Utils.java
+++ b/library/src/main/java/com/andview/refreshview/utils/Utils.java
@@ -1,19 +1,25 @@
package com.andview.refreshview.utils;
+import android.app.Activity;
import android.content.Context;
+import android.content.res.Configuration;
import android.graphics.Point;
-import android.support.v7.widget.GridLayoutManager;
-import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
-import android.support.v7.widget.StaggeredGridLayoutManager;
+import android.util.DisplayMetrics;
+import android.view.Display;
import android.view.View;
import android.view.ViewGroup;
+import android.view.Window;
import android.view.WindowManager;
-import android.widget.LinearLayout;
-import com.andview.refreshview.callback.IFooterCallBack;
+import androidx.recyclerview.widget.GridLayoutManager;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.recyclerview.widget.StaggeredGridLayoutManager;
+
import com.andview.refreshview.recyclerview.BaseRecyclerAdapter;
+import java.lang.reflect.Method;
+
public class Utils {
/**
@@ -51,28 +57,25 @@ public static void removeViewFromParent(View view) {
public static boolean isRecyclerViewFullscreen(RecyclerView viewGroup) {
if (viewGroup.getAdapter() instanceof BaseRecyclerAdapter) {
- int count = viewGroup.getChildCount();
-
- View lastchild = viewGroup.getChildAt(count - 1);
- if (lastchild instanceof IFooterCallBack) {
- lastchild = viewGroup.getChildAt(count - 2);
- }
- if (lastchild == null) {
- return false;
- }
- RecyclerView.LayoutParams lastLp = (RecyclerView.LayoutParams) lastchild.getLayoutParams();
- int lastBottomMargin = lastLp.bottomMargin;
- WindowManager wm = (WindowManager) viewGroup.getContext()
- .getSystemService(Context.WINDOW_SERVICE);
- int[] position = new int[2];
- int height = wm.getDefaultDisplay().getHeight();
- lastchild.getLocationOnScreen(position);
- LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) viewGroup.getLayoutParams();
- int bottomMargin = layoutParams.bottomMargin;
- int padding = viewGroup.getPaddingBottom();
-
+// int count = viewGroup.getChildCount();
+//
+// View lastchild = viewGroup.getChildAt(count - 1);
+// if (lastchild instanceof IFooterCallBack) {
+// lastchild = viewGroup.getChildAt(count - 2);
+// }
+// if (lastchild == null) {
+// return false;
+// }
+// RecyclerView.LayoutParams lastLp = (RecyclerView.LayoutParams) lastchild.getLayoutParams();
+// int lastBottomMargin = lastLp.bottomMargin;
+// int[] position = new int[2];
+// lastchild.getLocationOnScreen(position);
+// LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) viewGroup.getLayoutParams();
+// int bottomMargin = layoutParams.bottomMargin;
+// int padding = viewGroup.getPaddingBottom();
+// int height = getScreenHeight(viewGroup.getContext());
boolean atTop = findFirstCompletelyVisibleItemPosition(viewGroup) > 0;
- return (position[1] + lastchild.getHeight() + lastBottomMargin + bottomMargin + padding) >= height || atTop;
+ return /*(position[1] + lastchild.getHeight() + lastBottomMargin + bottomMargin + padding) >= height || */atTop;
}
return false;
}
@@ -133,7 +136,7 @@ public static int computeScrollVerticalDuration(int dy, int height) {
final int duration;
float absDelta = (float) Math.abs(dy);
duration = (int) (((absDelta / height) + 1) * 200);
- return Math.min(duration, 500);
+ return dy == 0 ? 0 : Math.min(duration, 500);
}
private static float distanceInfluenceForSnapDuration(float f) {
@@ -141,4 +144,98 @@ private static float distanceInfluenceForSnapDuration(float f) {
f *= 0.3f * Math.PI / 2.0f;
return (float) Math.sin(f);
}
+
+ public static boolean isScreenOriatationPortrait(Context context) {
+ return context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
+ }
+
+ public static int getDpi(Context context) {
+ int dpi = 0;
+ WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+ Display display = windowManager.getDefaultDisplay();
+ DisplayMetrics displayMetrics = new DisplayMetrics();
+ @SuppressWarnings("rawtypes")
+ Class c;
+ try {
+ c = Class.forName("android.view.Display");
+ @SuppressWarnings("unchecked")
+ Method method = c.getMethod("getRealMetrics", DisplayMetrics.class);
+ method.invoke(display, displayMetrics);
+ dpi = displayMetrics.heightPixels;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return dpi;
+ }
+
+ /**
+ * 获取 虚拟按键的高度
+ *
+ * @param context
+ * @return
+ */
+ public static int getBottomStatusHeight(Context context) {
+ int totalHeight = getDpi(context);
+ int contentHeight = getScreenHeight(context);
+ return totalHeight - contentHeight;
+ }
+
+ /**
+ * 标题栏高度
+ *
+ * @return
+ */
+ public static int getTitleHeight(Activity activity) {
+ return activity.getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTop();
+ }
+
+ /**
+ * 获得状态栏的高度
+ *
+ * @param context
+ * @return
+ */
+ public static int getStatusHeight(Context context) {
+
+ int statusHeight = -1;
+ try {
+ Class> clazz = Class.forName("com.android.internal.R$dimen");
+ Object object = clazz.newInstance();
+ int height = Integer.parseInt(clazz.getField("status_bar_height")
+ .get(object).toString());
+ statusHeight = context.getResources().getDimensionPixelSize(height);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return statusHeight;
+ }
+
+
+ /**
+ * 获得屏幕高度
+ *
+ * @param context
+ * @return
+ */
+ public static int getScreenHeight(Context context) {
+ WindowManager wm = (WindowManager) context
+ .getSystemService(Context.WINDOW_SERVICE);
+ DisplayMetrics outMetrics = new DisplayMetrics();
+ wm.getDefaultDisplay().getMetrics(outMetrics);
+ return outMetrics.heightPixels;
+ }
+
+ /**
+ * 获得屏幕宽度
+ *
+ * @param context
+ * @return
+ */
+ public static int getScreenWidth(Context context) {
+ WindowManager wm = (WindowManager) context
+ .getSystemService(Context.WINDOW_SERVICE);
+ DisplayMetrics outMetrics = new DisplayMetrics();
+ wm.getDefaultDisplay().getMetrics(outMetrics);
+ return outMetrics.widthPixels;
+ }
}
diff --git a/library/src/main/java/com/andview/refreshview/view/XWebView.kt b/library/src/main/java/com/andview/refreshview/view/XWebView.kt
new file mode 100644
index 0000000..ead9fb3
--- /dev/null
+++ b/library/src/main/java/com/andview/refreshview/view/XWebView.kt
@@ -0,0 +1,20 @@
+package com.andview.refreshview.view
+
+import android.content.Context
+import android.util.AttributeSet
+import android.webkit.WebView
+
+/**
+ * Created by 2144 on 2017/4/25.
+ */
+open class XWebView @JvmOverloads constructor(
+ private val mContext: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
+) : WebView(mContext, attrs, defStyleAttr) {
+
+ val isBottom: Boolean
+ get() = computeVerticalScrollRange() == height + scrollY
+
+ public override fun computeVerticalScrollRange(): Int {
+ return super.computeVerticalScrollRange()
+ }
+}
\ No newline at end of file
diff --git a/library/src/main/res/values/strings.xml b/library/src/main/res/values/strings.xml
index 029913b..361de33 100644
--- a/library/src/main/res/values/strings.xml
+++ b/library/src/main/res/values/strings.xml
@@ -7,6 +7,7 @@
正在刷新...
正在加载...
加载完成
+ 加载失败
上次更新时间:
加载完成
加载失败,请重试