Android MVP设计框架模板 之 漂亮ListView上拉刷新下拉加载更多

mvp的全称为Model-View-Presenter,Model提供数据,View负责显示,Controller/Presenter负责逻辑的处理。MVP与MVC有着一个重大的区别:在MVP中View并不直接使用Model,它们之间的通信是通过Presenter
(MVC中的Controller)来进行的,所有的交互都发生在Presenter内部,而在MVC中View会直接从Model中读取数据而不是通过 Controller。

项目中大部分是面对接口编程,通过P层可以预先将所有需要的接口功能写出来,进而进行实现,大大提高了项目高内聚,低耦合。适合于团队开发项目。

今天我们是用MVP的设计框架模板来实现一个ListView的上拉刷新下拉加载更多的功能。

项目结构如下图;

1、首先我们ListViewPresenters.java类,他的作用是,控制M业务逻辑层,去获取我们想要的数据,然后通知V层去更新他们对应的UI。由于我们的需求明确,就是实现Listview的上拉刷新,下拉加载更多,初始化控件,设置上拉下拉刷新监听。因此我们可以先把功能接口都写好,让ListViewPresenters去实现其功能即可。

package com.android.presenters;

import java.util.ArrayList;

import android.support.v4.app.FragmentActivity;
import android.view.View;

import com.android.handlers.ListViewHandle;
import com.android.services.ListViewService;
import com.android.services.si.IListViewService;
import com.android.view.ListViewFerris;
import com.android.view.vi.IListViewFerris;
import com.android.widget.listview.FerrisListView.OnStartListener;

public class ListViewPresenters {
	private IListViewFerris iListViewFerris;
	private IListViewService iListViewService;
	private FragmentActivity mActivity;
	private View view;
	private int index = 1;

	public ListViewPresenters(FragmentActivity mActivity2, View view2) {
		// TODO Auto-generated constructor stub
		this.mActivity = mActivity2;
		this.view = view2;
		this.iListViewFerris = new ListViewFerris(mActivity, view);
		this.iListViewService = new ListViewService();
	}

	/*
	 * 初始化View层里的控件
	 */
	public void onFindView() {
		iListViewFerris.onFindView();
	}
	/*
	 * 上啦刷新方法
	 */
	public void listViewRefresh(int index) {
		//post请求数据,获取数据,并且通过handler接口来通知View更新UI
		iListViewService.sendPost(index, new ListViewHandle() {
			@Override
			public void getData(ArrayList<String> msgs) {
				// TODO Auto-generated method stub
				//通过handler接口来通知UI去更新数据
				iListViewFerris.refresh(msgs);
			}
		});
	}
	/*
	 * 下拉加载更多方法
	 */
	public void listViewLoadMore(int index) {
		//post请求数据,获取数据,并且通过handler接口来通知View更新UI
		iListViewService.sendPost(index, new ListViewHandle() {
			@Override
			public void getData(ArrayList<String> msgs) {
				// TODO Auto-generated method stub
				//通过handler接口来通知UI去更新数据
				if (msgs == null) {
					iListViewFerris.showLoadingError();//获取数据失败显示通知
					iListViewFerris.loadMore(msgs);//停止加载更多
				} else {
					iListViewFerris.loadMore(msgs);//停止加载更多
				}

			}
		});
	}
	/*
	 * 为Listview设置上拉下拉刷新监听
	 */
	public void setRefreshOrLoadMoreListem() {
		// TODO Auto-generated method stub

		iListViewFerris.setRefreshOrLoadMoreListem(new Refresh(),
				new Loadmore());
	}

	/*
	 * 为Listview第一次,自动下拉刷新
	 */
	public void firstload() {
		// TODO Auto-generated method stub
		iListViewFerris.firstLoad();
	}

	/*
	 * 上拉刷新监听
	 */
	public class Refresh implements OnStartListener {

		@Override
		public void onStart() {
			// TODO Auto-generated method stub
			index = 1;
			listViewRefresh(index);

		}

	}
	/*
	 * 加载更多监听
	 */
	public class Loadmore implements OnStartListener {

		@Override
		public void onStart() {
			// TODO Auto-generated method stub
			listViewLoadMore(++index);
		}

	}

}

2、接着我们来看下UI层,我们需要更新哪些数据,需要为哪个UI去具体更新哪些东西。

package com.android.view.vi;

import java.util.ArrayList;

import com.android.widget.listview.FerrisListView.OnStartListener;

public interface IListViewFerris {
	public void onFindView();//初始化控件
	public void showLoadingError();//显示加载错误
	public void showLoadingSuccess();//显示加成功
	public void setNotifyListView();//刷新Listview
	public void refresh(ArrayList<String> msgs);//上拉刷新
	public void loadMore(ArrayList<String> msgs);//下拉加载更多
	public void setRefreshOrLoadMoreListem(OnStartListener refresh, OnStartListener loadmore);//设置上拉下拉刷新监听
	public void firstLoad();//首次自动上拉刷新
}

具体UI层实现的具体方法,主要是 上拉刷新,下拉加载更多,显示错误成功状态,以及初始化控件等方法。

package com.android.view;

import java.util.ArrayList;

import android.support.v4.app.FragmentActivity;
import android.view.View;

import com.android.adapter.ListViewAdapter;
import com.android.futilssimple.R;
import com.android.utils.ToastUtils;
import com.android.view.vi.IListViewFerris;
import com.android.widget.listview.FerrisListView;
import com.android.widget.listview.FerrisListView.OnStartListener;
import com.android.widget.listview.SimpleFooter;
import com.android.widget.listview.SimpleHeader;

public class ListViewFerris implements IListViewFerris{
	private FragmentActivity mActivity;
	private View view;
	private FerrisListView listView;
	private ListViewAdapter adapter;
	public ListViewFerris(FragmentActivity mActivity,View view) {
		// TODO Auto-generated constructor stub
		this.mActivity=mActivity;
		this.view=view;
	}

	//初始化view
	@Override
	public void onFindView() {
		// TODO Auto-generated method stub
		if(mActivity==null||view==null){
			return;
		}

		listView = (FerrisListView)view.findViewById(R.id.zListView);
		adapter=new ListViewAdapter(mActivity);

		// 设置默认偏移量,主要用于实现透明标题栏功能。(可选)
        float density = mActivity.getResources().getDisplayMetrics().density;
        listView.setFirstTopOffset((int) (50 * density));

        // 设置下拉刷新的样式(可选,但如果没有Header则无法下拉刷新)
        SimpleHeader header = new SimpleHeader(mActivity);
        header.setTextColor(0xff0066aa);
        header.setCircleColor(0xff33bbee);
        listView.setHeadable(header);

        // 设置加载更多的样式(可选)
        SimpleFooter footer = new SimpleFooter(mActivity);
        footer.setCircleColor(0xff33bbee);
        listView.setFootable(footer);

	}

	//显示加载失败
	@Override
	public void showLoadingError() {
		// TODO Auto-generated method stub
		ToastUtils.showToast(mActivity, "加载失败");
	}

	//显示加载成功
	@Override
	public void showLoadingSuccess() {
		// TODO Auto-generated method stub
		ToastUtils.showToast(mActivity, "加载成功");
	}

	//刷新数据
	@Override
	public void setNotifyListView() {
		// TODO Auto-generated method stub
		if(adapter!=null){
			adapter.notifyDataSetChanged();
		}
	}

	//填充刷新数据
	@Override
	public void refresh(ArrayList<String> msgs) {
		// TODO Auto-generated method stub
		if(msgs!=null&&msgs.size()>0){
			if(listView.getAdapter()==null){
				listView.setAdapter(adapter);
				adapter.setRefresh(msgs);
			}else{

				adapter.setRefresh(msgs);
			}
			listView.setRefreshSuccess("加载成功"); // 通知加载成功
			listView.startLoadMore(); // 开启LoadingMore功能
		}else{
			listView.setRefreshFail("加载失败");
		}

	}

	//填充加载更多数据
	@Override
	public void loadMore(ArrayList<String> msgs) {
		// TODO Auto-generated method stub
		if(msgs!=null&&msgs.size()>0){
			if(listView.getAdapter()==null){
				listView.setAdapter(adapter);
				adapter.setData(msgs);
			}else{
				adapter.setData(msgs);
			}

			listView.setLoadMoreSuccess();
		}else{
			listView.stopLoadMore();
		}

	}

	//为Listview设置首次自动上拉刷新
	@Override
	public void firstLoad(){
		listView.refresh(); // 主动下拉刷新
	}

	//为Listview设置上拉以及下拉刷新
	@Override
	public void setRefreshOrLoadMoreListem(OnStartListener refresh,
			OnStartListener loadmore) {
		// TODO Auto-generated method stub
		listView.setOnRefreshStartListener(refresh);
		listView.setOnLoadMoreStartListener(loadmore);
	}

}

3、我们来看下业务逻辑层,主要是通过模拟POST在后台请求数据,然后将获取的数据,返回给P层,由P层去将数据交予V层来更新UI界面。

package com.android.services.si;

import com.android.handlers.ListViewHandle;

public interface IListViewService {

	//发送post请求
	public void sendPost(int index,ListViewHandle handle);
}

业务逻辑才具体实现的功能如下:

package com.android.services;

import java.util.ArrayList;

import android.os.Handler;

import com.android.futils.task.FTaskPool;
import com.android.futils.task.TaskItem;
import com.android.handlers.ListViewHandle;
import com.android.services.si.IListViewService;

public class ListViewService implements IListViewService {
	String[] data={"加拿大","瑞典","澳大利亚","瑞士","新西兰","挪威","丹麦","芬兰","奥地利","荷兰","德国","日本","比利时","意大利","英国"};
	public ListViewService() {
		// TODO Auto-generated constructor stub
	}

	private Handler handler=new Handler();
	private ArrayList<String> msgs;

	@Override
	public void sendPost(int index, ListViewHandle handle) {
		// TODO Auto-generated method stub
		switch (index) {
		case 1:
			getData(index,handle);
			break;
		case 2:
			getData(index,handle);
			break;
		case 3:
			getData(index,handle);
			break;
		case 4:
			getData(index,handle);
			break;
		case 5:
			getData(index,handle);
			break;
		case 6:
			getData(index,handle);
			break;
		default:
			msgs=null;
			handle.getData(msgs);
			break;
		}
	}

	private synchronized void getData(final int index, final ListViewHandle handle) {
		// TODO Auto-generated method stub
		  handler.postDelayed(new Runnable() {
	            @Override
	            public void run() {
	            	FTaskPool.getInstance().execute(new TaskItem() {

	        			@Override
	        			public void doMain() {//在前台显示数据
	        				// TODO Auto-generated method stub
	        				if(handle!=null){
	        					handle.getData(msgs);
	        				}

	        			}

	        			@Override
	        			public void doBack() {//在后台处理数据
	        				// TODO Auto-generated method stub
	        				msgs=new ArrayList<String>();
	        				for(String d:data){
	        					msgs.add(index+"、"+d);
	        				}
	        			}
	        		});
	            }
	        }, 2 * 1000);//延迟2秒后执行

	}

}

4、最后,我们来看下Fragment里面如来调用这个P层,来控制MV进行数据的获取以及更新

package com.android.fragment;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.android.futilssimple.R;
import com.android.presenters.ListViewPresenters;

public class ListViewFragment extends Fragment {
	private ListViewPresenters listViewPresenters;

    public ListViewFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
    	View rootView = inflater.inflate(R.layout.listviewfragment, container, false);
    	listViewPresenters=new ListViewPresenters(getActivity(), rootView);//新建一个控制器
    	listViewPresenters.onFindView();//初始化view
    	listViewPresenters.setRefreshOrLoadMoreListem();//设置刷新监听
    	listViewPresenters.firstload();//首次自动上拉刷新
        return rootView;
    }

}

5、源码demo稍后上传

时间: 2024-12-11 19:50:13

Android MVP设计框架模板 之 漂亮ListView上拉刷新下拉加载更多的相关文章

Android 自定义 ListView 上下拉动&ldquo;刷新最新&rdquo;和&ldquo;加载更多&rdquo;歌曲列表

本文内容 环境 测试数据 项目结构 演示 参考资料 本文演示,上拉刷新最新的歌曲列表,和下拉加载更多的歌曲列表.所谓"刷新最新"和"加载更多"是指日期.演示代码太多,点击此处下载,自己调试一下. 下载 Demo 环境 Windows 2008 R2 64 位 Eclipse ADT V22.6.2,Android 4.4.3 SAMSUNG GT-I9008L,Android OS 2.2.2 测试数据 本演示的歌曲信息,共有 20 条,包括歌手名.歌曲名.时长.缩

Android下拉刷新库,利用viewdraghelper实现,集成了下拉刷新,底部加载更多,数据初始加载显示loading等功能

项目Github地址:https://github.com/sddyljsx/pulltorefresh Android下拉刷新库,利用viewdraghelper实现. 集成了下拉刷新,底部加载更多,以及刚进入加载数据的loadview.包括了listview与gridview的改写. 效果1: 效果2: 效果3: 效果4: 效果5: 使用说明: imageList=(ListView)findViewById(R.id.image_list); imageAdapter=new ImageA

Android ListView 下拉刷新 点击加载更多

最近项目中用到了ListView的下拉刷新的功能,总结了一下前辈们的代码,单独抽取出来写了一个demo作为示例. 效果图 下拉刷新: 加载更多: CustomListView.java [java] view plaincopy package com.example.uitest.view; import java.util.Date; import com.example.uitest.R; import android.content.Context; import android.uti

Android之 RecyclerView,CardView 详解和相对应的上拉刷新下拉加载

随着 Google 推出了全新的设计语言 Material Design,还迎来了新的 Android 支持库 v7,其中就包含了 Material Design 设计语言中关于 Card 卡片概念的实现 -- CardView.RecyclerView也是谷歌V7包下新增的控件,用来替代ListView的使用,在RecyclerView标准化了ViewHolder类似于ListView中convertView用来做视图缓存. RecyclerView的优点就是,他可以通过设置LayoutMan

Android——Xlistview上拉刷新下拉加载

配置网络权限+xutils包+gson包 代码如下: values下修改strings添加 直接粘 <?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">XListView刷新</string> <string name="hello_world">Hello world!

自定义ListView实现下拉刷新,下拉加载的功能

package com.loaderman.myrefreshlistviewdemo; import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.animation.Animation; import android

Android第二十三期 - 256k的ListView下拉刷新和滚动加载数据

代码已经

Android如何定制一个下拉刷新,上滑加载更多的容器

前言 下拉刷新和上滑加载更多,是一种比较常用的列表数据交互方式. android提供了原生的下拉刷新容器 SwipeRefreshLayout,可惜样式不能定制. 于是打算自己实现一个专用的.但是下拉刷新和上滑,非常考验对android布局与父子触摸机制的功底,因此参考gitHub上的一个热门的下拉刷新项目 之所以选择他是因为它一个类就完成了所有View的适配,非常的精简强力. 需求 咱对下拉刷新.上滑加载更多的控件,需求如下: 1:下拉刷新,拖动到一定距离,提示文字变成 放手刷新 2:刷新完成

android 安卓 listview 支持下拉刷新 上拉加载更多

[1]重写listView import java.text.SimpleDateFormat; import java.util.Date; import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.ViewGrou