前言
app中最常见的场景莫过于下拉刷新和自动加载的功能了,最经典的开源组件就是Android-PullToRefresh,但本文主要是使用的是android-Ultra-Pull-To-Refresh,地址是:https://github.com/liaohuqiu/android-Ultra-Pull-To-Refresh
本次demo的编辑环境为android studio,java1.8
截图
使用
1.本示例依赖jar如下:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'de.greenrobot:eventbus:2.4.0'
compile('in.srain.cube:ultra-ptr:1.0.9.1-SNAPSHOT@aar') {
exclude group: 'in.srain.cube', module: 'clog'
}
compile('in.srain.cube:cube-sdk:1.0.44.33-SNAPSHOT@aar') {
exclude group: 'in.srain.cube', module: 'clog'
}
}
2.xml中的内容:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="loadmore.example.jan.org.loadmoredemo.MainActivity">
<in.srain.cube.views.ptr.PtrClassicFrameLayout
android:id="@+id/load_more_list_view_ptr_frame"
android:layout_width="match_parent"
android:layout_height="match_parent">
<in.srain.cube.views.loadmore.LoadMoreListViewContainer
android:id="@+id/load_more_list_view_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/cube_mints_white">
<ListView
android:id="@+id/load_more_listview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="@null"
android:fadingEdge="none"
android:listSelector="@android:color/transparent"
android:paddingLeft="12dp"
android:paddingRight="12dp"
android:scrollbarStyle="outsideOverlay" />
</in.srain.cube.views.loadmore.LoadMoreListViewContainer>
</in.srain.cube.views.ptr.PtrClassicFrameLayout>
</RelativeLayout>
PtrClassicFrameLayout 是一个可以起到下拉刷新的实现的父类布局,而LoadMoreListViewContainer则是加载更多的布局控件。
3.MainActivity.java demo主要的代码实现,步骤和说明已注释
/**
* 利用android-Ultra-Pull-To-Refresh,上拉刷新和上拉加载的简单的dome
*/
public class MainActivity extends AppCompatActivity {
private PtrFrameLayout mPtrFrameLayout;
private LoadMoreListViewContainer mLoadMoreListViewContainer;
private ListView mListView;
private List<String> mockStrList = new ArrayList<>();
private int start = 0;
private int count = 15;
private PagedListViewDataAdapter<String> mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//1.find the listview
mListView = (ListView) findViewById(R.id.load_more_listview);
// 为listview的创建一个headerview,注意,如果不加会影响到加载的footview的显示!
View headerMarginView = new View(this);
headerMarginView.setLayoutParams(new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, LocalDisplay.dp2px(20)));
mListView.addHeaderView(headerMarginView);
//2.绑定模拟的数据
final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mockStrList);
mListView.setAdapter(adapter);
//3.设置下拉刷新组件和事件监听
mPtrFrameLayout = (PtrFrameLayout) findViewById(R.id.load_more_list_view_ptr_frame);
mPtrFrameLayout.setLoadingMinTime(1000);
mPtrFrameLayout.setPtrHandler(new PtrHandler() {
@Override
public boolean checkCanDoRefresh(PtrFrameLayout frame, View content, View header) {
// here check list view, not content.
return PtrDefaultHandler.checkContentCanBePulledDown(frame, mListView, header);
}
@Override
public void onRefreshBegin(PtrFrameLayout frame) {
//实现下拉刷新的功能
Log.i("test", "-----onRefreshBegin-----");
mPtrFrameLayout.postDelayed(new Runnable() {
@Override
public void run() {
mockStrList.clear();
start = 0;
mockStrList.addAll(getMockData(start, count));
mPtrFrameLayout.refreshComplete();
//第一个参数是:数据是否为空;第二个参数是:是否还有更多数据
mLoadMoreListViewContainer.loadMoreFinish(false, true);
adapter.notifyDataSetChanged();
}
}, 500);
}
});
//设置延时自动刷新数据
mPtrFrameLayout.postDelayed(new Runnable() {
@Override
public void run() {
mPtrFrameLayout.autoRefresh(false);
}
}, 200);
//4.加载更多的组件
mLoadMoreListViewContainer = (LoadMoreListViewContainer) findViewById(R.id.load_more_list_view_container);
mLoadMoreListViewContainer.setAutoLoadMore(true);//设置是否自动加载更多
mLoadMoreListViewContainer.useDefaultHeader();
//5.添加加载更多的事件监听
mLoadMoreListViewContainer.setLoadMoreHandler(new LoadMoreHandler() {
@Override
public void onLoadMore(LoadMoreContainer loadMoreContainer) {
//模拟加载更多的业务处理
mLoadMoreListViewContainer.postDelayed(new Runnable() {
@Override
public void run() {
start++;
mockStrList.addAll(getMockData(start * 10, count));
if (start * 10 > 30) {
// mLoadMoreListViewContainer.loadMoreFinish(true, false);
//以下是加载失败的情节
int errorCode = 0;
String errorMessage = "加载失败,点击加载更多";
mLoadMoreListViewContainer.loadMoreError(errorCode, errorMessage);
} else {
mLoadMoreListViewContainer.loadMoreFinish(false, true);
}
adapter.notifyDataSetChanged();
}
}, 1000);
}
});
}
/**
* 做一个简单的内容数据
* @param start 开始位置
* @param count 每次拉取的数量
* @return
*/
private List<String> getMockData(int start, int count) {
List<String> slist = new ArrayList<String>();
for (int i = start; i < start + count; i++) {
slist.add("内容编号:" + i);
}
return slist;
}
}
-----------------------------更新时间:2016年2月24日 17:08:32---------------------------------------------------------
自定义底部加载内容
1.首先,确认加载状态,实现LoadMoreUIHandler接口,代码如下:
public interface LoadMoreUIHandler {
public void onLoading(LoadMoreContainer container);
public void onLoadFinish(LoadMoreContainer container, boolean empty, boolean hasMore);
public void onWaitToLoadMore(LoadMoreContainer container);
public void onLoadError(LoadMoreContainer container, int errorCode, String errorMessage);
}
2.创建自己想要的加载布局,同时要实现 LoadMoreUIHandler接口
/**
* Created by jan on 2016/2/24.
*/
public class ILoadMoreFooterView extends RelativeLayout implements LoadMoreUIHandler {
private ImageView loadingImage;
private TextView loadText;
public ILoadMoreFooterView(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public ILoadMoreFooterView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setupViews();
}
public ILoadMoreFooterView(Context context) {
this(context, null);
}
private void setupViews() {
LayoutInflater.from(getContext()).inflate(R.layout.custom_loadmore_footer, this);
loadingImage = (ImageView) findViewById(R.id.loading_progress_icon);
loadText = (TextView) findViewById(R.id.loading_text);
setVisibility(GONE);
}
@Override
public void onLoading(LoadMoreContainer container) {
setVisibility(VISIBLE);
loadingImage.setVisibility(VISIBLE);
loadText.setText(R.string.loading_text);
final RotateAnimation anim = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
anim.setInterpolator(new LinearInterpolator());
anim.setRepeatCount(-1);
anim.setDuration(1000);
loadingImage.setImageResource(R.drawable.progress_loading2);
loadingImage.startAnimation(anim);
}
@Override
public void onLoadFinish(LoadMoreContainer container, boolean empty, boolean hasMore) {
if (!hasMore) {
setVisibility(VISIBLE);
if (empty) {
loadText.setText(R.string.loading_empty);
} else {
loadText.setText(R.string.loading_finish_empty);
}
loadingImage.setVisibility(INVISIBLE);
} else {
setVisibility(INVISIBLE);
}
}
@Override
public void onWaitToLoadMore(LoadMoreContainer container) {
setVisibility(VISIBLE);
loadText.setText(R.string.load_click_more);
loadingImage.setVisibility(INVISIBLE);
}
@Override
public void onLoadError(LoadMoreContainer container, int errorCode, String errorMessage) {
loadingImage.clearAnimation();
loadingImage.setImageResource(R.drawable.no_order_get);
loadText.setText(R.string.loading_finish_error);
}
}
3.最后的使用,在之前的代码中取消使用默认的“加载中”的footview,更换自己的view,代码如下
ILoadMoreFooterView customMoreView = new ILoadMoreFooterView(this);
AbsListView.LayoutParams lp = new AbsListView.LayoutParams(-2, LocalDisplay.dp2px(80));
customMoreView.setLayoutParams(lp);
mLoadMoreListViewContainer.setLoadMoreView(customMoreView);
mLoadMoreListViewContainer.setLoadMoreUIHandler(customMoreView);
// mLoadMoreListViewContainer.useDefaultHeader();
效果图