前言
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); }
/** * 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); } }
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();