MVCHelper
实现下拉刷新,滚动底部自动加载更多,分页加载,自动切换显示网络失败布局,暂无数据布局,支持任意view,支持切换主流下拉刷新框架,真正的android MVC架构,listview,RecyclerView,refresh,loadmore
Install / Use
/learn @LuckyJayce/MVCHelperREADME
[TOC]
MVCHelper主要用于下拉刷新加载,失败,加载,空数据,成功的界面切换。
MVCHelper +(IDataSource或ITask)+ IDataAdapter + 下拉刷新控件 + 布局切换(ILoadViewFactory,ILoadView,ILoadMoreView)
原先Task的代码已经抽离出单独一个类库:https://github.com/LuckyJayce/Task
历史版本和更新信息
https://github.com/LuckyJayce/MVCHelper/releases
常见疑惑集锦
Gradle导入
1.必须导入:
//MVCHelper核心类库
compile 'com.shizhefei:MVCHelper-Library:1.4.0'
//里面有使用recyclerview,所以需要导入recyclerview,版本不限
compile 'com.android.support:recyclerview-v7:28.0.0'
2.可选:
<1> 使用 https://github.com/LuckyJayce/CoolRefreshView 的刷新控件导入 支持任意View的刷新 ,支持自定义Header,支持NestedScrollingParent,NestedScrollingChild的事件分发,嵌套ViewPager不会有事件冲突
//里面包含一个MVCCoolHelper 是适配这个控件的 MVCHelper
compile 'com.shizhefei:MVCHelper-CoolRefresh:1.4.0'
compile 'com.shizhefei:CoolRefreshView:1.0.1'
//v4版本不限
compile 'com.android.support:support-v4:28.0.0'
<2> 使用 https://github.com/chrisbanes/Android-PullToRefresh 的刷新控件导入
//里面包含一个MVCPullrefshHelper 是适配这个控件的 MVCHelper
compile 'com.shizhefei:MVCHelper-Pullrefresh:1.4.0'
//由于没有找到gradle排至,我自己把它上传到jcenter上
compile 'com.shizhefei:pulltorefresh:1.0.1'
<3> 使用 https://github.com/liaohuqiu/android-Ultra-Pull-To-Refresh 的刷新控件导入
//里面包含一个MVCUltraHelper 是适配这个控件的 MVCHelper
compile 'com.shizhefei:MVCHelper-UltraRefresh:1.4.0'
//这里6月29号目前最新的,要实时关注新版本去秋大的网站上去看
compile 'in.srain.cube:ultra-ptr:1.0.11'
<4> 使用android v4的SwipeRefreshLayout的作为刷新控件导入
//里面包含一个MVCSwipeRefreshHelper 是适配这个控件的 MVCHelper
compile 'com.shizhefei:MVCHelper-SwipeRefresh:1.4.0'
//v4包应该都有导入吧,v7包里面包含v4包, v4版本不限
compile 'com.android.support:support-v4:28.0.0'
<5> 测试用例,可以方便的查看MVCHelper,Task的运行情况和返回数据,还提供了修改接口字段,用于接口测试很方便哦
//MVCHelper的测试用例,继承ABSTestCaseFragment实现List<TestCaseData> getTestCaseDatas()方法
compile 'com.shizhefei:task-testcese:1.0.0'
//里面用到了gson
compile 'com.google.code.gson:gson:2.2.4'
结构

这里V和M是没有联系的,或许可以理解为是MVP结构吧.
类图:
https://raw.githubusercontent.com/LuckyJayce/MVCHelper/master/raw/MVCHelper%E7%B1%BB%E5%9B%BE.png
效果图:

一、 MVCHelper
MVCHelper. 实现下拉刷新,滚动底部自动加载更多,分页加载,自动切换显示网络失败布局,暂无数据布局,,真正的MVC架构.
1.Model (IDataSource<DATA>)数据源,加载数据
同步请求实现IDataSource,异步请求(okhttp,volley,rxjava+retrofit)实现IAsyncDataSource
<1>同步请求(直接返回结果
//数据源
public interface IDataSource<DATA> {
// 获取刷新的数据
public DATA refresh() throws Exception;
// 获取加载更多的数据
public DATA loadMore() throws Exception;
// 是否还可以继续加载更多
public boolean hasMore();
}
例如:分页加载书籍列表数据 public class BooksDataSource implements IDataSource<List<Book>> { private int page = 1; private int maxPage = 5; @Override public List<Book> refresh() throws Exception { return loadBooks(1); } @Override public List<Book> loadMore() throws Exception { return loadBooks(page + 1); }
private List<Book> loadBooks(int page) {
List<Book> books = new ArrayList<Book>();
for (int i = 0; i < 20; i++) {
books.add(new Book("page" + page + " Java编程思想 " + i, 108.00d));
}
this.page = page;
return books;
}
@Override
public boolean hasMore() {
return page < maxPage;
}
}
<2>异步请求(就是请求等待回调函数返回结果
/**
* 异步数据源(比如Volley,OkHttp等异步请求使用)
* @param <DATA>
*/
public interface IAsyncDataSource<DATA> {
/**
* 获取刷新的数据
*
* @param sender 用于请求结束时发送数据给MVCHelper,MVCHelper再通知IDataAdapter调用notifyDataChenge方法
* @return 用于提供外部取消请求的处理.比如执行refresh还没请求结束又执行refresh,就会通过上次的RequestHandle取消上次的请求.MVCHelper的destroy也会用这个取消请求
* @throws Exception
*/
RequestHandle refresh(ResponseSender<DATA> sender) throws Exception;
/**
* 获取加载更多的数据
*
* @param sender 用于请求结束时发送数据给MVCHelper,MVCHelper再通知IDataAdapter调用notifyDataChenge方法
* @return 用于提供外部取消请求的处理.比如执行refresh还没请求结束又执行refresh,就会通过上次的RequestHandle取消上次的请求.MVCHelper的destroy也会用这个取消请求
* @throws Exception
*/
RequestHandle loadMore(ResponseSender<DATA> sender) throws Exception;
/**
* 是否还可以继续加载更多
*
* @return
*/
boolean hasMore();
}
例如:OkHttp请求
public class BooksOkHttpNormal_DataSource implements IAsyncDataSource<List<Book>> {
private int mPage;
private int mMaxPage = 5;
public BooksOkHttpNormal_DataSource() {
super();
}
@Override
public RequestHandle refresh(ResponseSender<List<Book>> sender) throws Exception {
return loadBooks(sender, 1);
}
@Override
public RequestHandle loadMore(ResponseSender<List<Book>> sender) throws Exception {
return loadBooks(sender, mPage + 1);
}
@Override
public boolean hasMore() {
return mPage < mMaxPage;
}
private RequestHandle loadBooks(final ResponseSender<List<Book>> sender, final int page) throws Exception {
Request request = new Request.Builder().url("https://www.baidu.com").get().build();
Call call = OkHttpUtils.client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
//send 要放在最后一句(请求结束)
sender.sendError(e);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
final List<Book> books = new ArrayList<Book>();
for (int i = 0; i < 15; i++) {
books.add(new Book("page" + page + " Java编程思想 " + i, 108.00d));
}
mPage = page;
//send 要放在最后一句(请求结束)
sender.sendData(books);
}
});
return new OKHttpRequestHandle(call);
}
}
public class OKHttpRequestHandle implements RequestHandle {
private final Call call;
public OKHttpRequestHandle(Call call) {
super();
this.call = call;
}
@Override
public void cancle() {
call.cancel();
}
@Override
public boolean isRunning() {
return false;
}
}
例如:使用 MVCHelper-OkHttp
public class BooksOkHttp_AsyncDataSource implements IAsyncDataSource<List<Book>> {
private int mPage;
private int mMaxPage = 5;
@Override
public RequestHandle refresh(ResponseSender<List<Book>> sender) throws Exception {
return loadBooks(sender, 1);
}
@Override
public RequestHandle loadMore(ResponseSender<List<Book>> sender) throws Exception {
return loadBooks(sender, mPage + 1);
}
@Override
public boolean hasMore() {
return mPage < mMaxPage;
}
private RequestHandle loadBooks(final ResponseSender<List<Book>> sender, final int page) throws Exception {
GetMethod method = new GetMethod("https://www.baidu.com");
method.addHeader("a", "aaaaa");
method.addParam("api_key", "75ee6c644cad38dc8e53d3598c8e6b6c");
//method 里面已经封装了sender.sendData 和 sendError的方法,只要关心ResponseParser解析Response返回数据就好
method.executeAsync(sender, new ResponseParser<List<Book>>() {
@Override
public List<Book> parse(Response response) throws Exception {
List<Book> books = new ArrayList<Book>();
for (int i = 0; i < 15; i++) {
books.add(new Book("page" + page + " Java编程思想 " + i, 108.00d));
}
mPage = page;
return books;
}
});
return method;
}
}
**详细写法请看
https://github.com/LuckyJayce/MVCHelper/tree/master/app/src/main/java/com/shizhefei/test/models/datasource
里面有
2.View(IDataAdapter<DATA>) 视图,显示数据
这里不是指Android的view,而是显示数据的概念和显示逻辑
public interface IDataAdapter<DATA> {
public abstract void notifyDataChanged(DATA data, boolean isRefresh);
public abstract DATA getData();
public boolean isEmpty();
}
例如:分页显示书籍列表数据 public class BooksAdapter extends BaseAdapter implements IDataAdapter<List<Book>> { private List<Book> books = new ArrayList<Book>(); private LayoutInflater inflater; public BooksAdapter(Context context) { super(); inflater = LayoutInflater.from(context); } @Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { convertView = inflater.inflate(R.layout.item_book, parent, false); } TextView textView = (TextView) convertView; textView.setText(books.get(position).getName()); return convertView; }
@Override
public void notifyDataChanged(List<Book> data, boolean isRefresh) {
if (isRefresh) {
books.clear();
}
books.addAll(data);
notifyDataSetChanged();
}
@Override
public int getCount() {
return books.size();
}
@Override
public List<Book> getData() {
return books;
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
}
3.Controller (Activity,Fragment,MVCHelper)控制器
控制器负责调用读取数据,调用显示数据,处理用户交互
Activity负责调度,代码如下
public class MainActivity extends Activity {
private MVCHelper<List<Book>> mvcHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 设置LoadView的factory,用于创建用户自定义的加载失败,加载中,加载更多等布局
// MVCHelper.setLoadViewFractory(new LoadViewFractory());
PullToRefreshListView refreshListView = (PullToRefreshListView) findViewById(R.id.pullToRefreshListView);
mvcHelper = new MVCPullrefshHelper<List<Book>>(refreshListView);
// 设置数据源
mvcHelper.setDataSource(new BooksDataSource());
// 设置适配器
mvcHelper.setAdapter(new BooksAdapter(this));
// 加载数据
mvcHelper.refresh();
}
@Override
protected voi
Related Skills
node-connect
349.2kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
109.5kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
349.2kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
349.2kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
