分组列表,带下拉刷新和上拉加载更多【项目地址在文章最后!!】
效果图:
实现过程,借鉴PinnedHeadListView,但是该demo没有下拉刷新功能,故将该控件整合到PullToRefresh 库中,【PullToRefresh 库为第三方开源库,附含各种下拉刷新和加载控件】最后形成自己的控件
项目源代码:
整合过程:
一、整合PullToRefreshListView 和 PinnedHeadListView库
1、PullToRefreshListView做为library,主工程引入
2、通过拷贝src/com/handmark/pulltorefresh/library/PullToRefreshListView.java类到新建的PullToRefreshUpLoadPinnedHeaderListView.java类中;
修改:createListView方法,
protected ListView createListView(Context context, AttributeSet attrs) {
final ListView lv;
// if (VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) {
// lv = new InternalListViewSDK9(context, attrs);
// } else {
// lv = new InternalListView(context, attrs);
// }
lv = new UpLoadPinnedHeaderListView(context, attrs);
return lv;
}
3、提示需要导入PinnedSectionedHeaderAdapter,而PinnedSectionedHeaderAdapter是 PinnedHeadListView的内部方法,故拷贝可用的PinnedHeadListView到PullToRefresh库中
4、之后提示PinnedHeadListView中找不到SectionedBaseAdapter,从可用的PinnedHeadListView工程中拷贝到PullToRefresh库中。
最后PullToRefreshListView库新增的目录结构为:
二、主工程中调用
1、layout中引入该listView:
<com.handmark.pulltorefresh.library.PullToRefreshUpLoadPinnedHeaderListView
xmlns:ptr="http://schemas.android.com/apk/res-auto"
android:id="@+id/pinnedListView"
android:layout_hljs-string">"match_parent"
二、主工程目录结构:
activity中
实现下拉刷新和上拉加载需要在activity调用中继承如下两个接口:
OnLoadingMoreLinstenerInPull, OnRefreshListener
调用过程完成代码【读取assets中假数据进行显示,主要难点是解析数据进行重组成控件所需要的数据结构。。下面代码已经列出解析过程。可以直接用】:
/**
* 带分组功能的listView,待上拉加载和下拉刷新功能
*
* @author zp
*
* 2015年11月22日
*/
public class ZActivity_tixianHistory_groupList extends Activity implements
OnLoadingMoreLinstenerInPull, OnRefreshListener,
OnItemClickListener {
int pageSize = 10;
/**
* 待section的listView,控件
*/
PullToRefreshUpLoadPinnedHeaderListView pullLoadpinnedlistView;
ListView pinnedlistView;
ZAdapter_tixian_recordHistory tixianAdapter;//
private RelativeLayout moredata;
private View progressBarView;
private TextView progressBarTextView;
private AnimationDrawable loadingAnimation;
private boolean isLoading = false;
private LayoutInflater inflater;
/**
* 数组分组使用参数
*/
List listGroup = new ArrayList();// 组容器。存放所有的组,用于listView参数
List listLast = new ArrayList();// 存放分好组的数据模型,用于显示到listview
ZModel_tixian_record model = null;// 实体类对象
List list_son_collect;// 保存实体列表中内容数据
CashWithDrawRequestList son_record_detail;// 某个组下的list容器
int pageno = 1;
ProgressDialog progressDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.zgetcash_record);
initViews();
}
private void initViews() {
// 1、 初始化PinnedListView
pinnedlistView = getListView();
/**
* 加载底部上拉加载视图
*/
LayoutInflater inflator = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater = LayoutInflater.from(this);
moredata = (RelativeLayout) inflater.inflate(R.layout.foot_loading,
null);
progressBarView = (View) moredata
.findViewById(R.id.loadmore_foot_progressbar);
progressBarTextView = (TextView) moredata
.findViewById(R.id.loadmore_foot_text);
loadingAnimation = (AnimationDrawable) progressBarView.getBackground();
pinnedlistView.addFooterView(moredata);
((UpLoadPinnedHeaderListView) pinnedlistView)
.setLoadingMoreListener(this);
startTixianRecordList();// 此处请求接口获取数据。此处使用假数据代替演示效果
}
public ListView getListView() {
pullLoadpinnedlistView = (PullToRefreshUpLoadPinnedHeaderListView) findViewById(R.id.pinnedListView);
pullLoadpinnedlistView.setOnRefreshListener(this);
return pullLoadpinnedlistView.getRefreshableView();
}
@Override
public void OnLoadingMore() {
progressBarView.setVisibility(View.VISIBLE);
progressBarTextView.setVisibility(View.VISIBLE);
loadingAnimation.start();
if (!isLoading) {
isLoading = true;
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
loadingFinished();
}
}, 1200);
}
}
public void loadingFinished() {
if (null != loadingAnimation && loadingAnimation.isRunning()) {
loadingAnimation.stop();
}
progressBarView.setVisibility(View.GONE);
progressBarTextView.setVisibility(View.GONE);
isLoading = false;
tixianAdapter.notifyDataSetChanged();
}
@Override
public void onItemClick(AdapterView> parent, View view, int position,
long id) {// 筛选项点击后
}
/**
* 模拟数据(从assets中读取json解析出其中的list,然后进行分组处理)
*/
public String getDataFromAsset(String datasource) {
byte b[] = this.getData(this, datasource);
String str = "";
try {
str = new String(b, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
System.out.println("读取asset假数据==" + str);
return str;
}
/**
* 将得到的 普通list集合 分组重组以适用于与分组listView
*
* @param rrs
* :接口返回的list数据
*/
public void transferForGroupList(
List list_cash) {
int groupSize = 0;
for (int i = 0; i <(list_cash).size(); i++) {
// 如果不含该组就添加到组中,保证listGroup中不存在重复组名
if (!listGroup.contains(dealDataForYM(list_cash.get(i)
.getApplytime()))) {
model = new ZModel_tixian_record();// 实体类
listGroup.add(dealDataForYM(list_cash.get(i).getApplytime()));// 所有的组
groupSize++;
model.setGroupTime(dealDataForYM(list_cash.get(i)
.getApplytime()));
list_son_collect = new ArrayList();
// 组和子列表分开保存
for (int j = 0; j // 遍历所有数据,如果含有该组名就添加到组对应的list中
if (dealDataForYM(list_cash.get(j).getApplytime()).equals(
listGroup.get(groupSize - 1))) {
son_record_detail = new CashWithDrawRequestList();
son_record_detail.amount = list_cash.get(j).getAmount();
son_record_detail.applytime = list_cash.get(j)
.getApplytime();
son_record_detail.status = list_cash.get(j).getStatus();
son_record_detail.fee = list_cash.get(j).getStatus();
list_son_collect.add(son_record_detail);
}
}
model.setCashWithDrawRequestList(list_son_collect);
listLast.add(model);
}
}
}
/**
* 截取出年月(2015-09)
*
* @param datetotal
* @return
*/
public String dealDataForYM(String datetotal) {
String res = "";
res = datetotal.substring(0,
datetotal.indexOf("-", datetotal.indexOf("-") + 1));// 截取到第二个“-”之前
System.out.println("截取时间年月==" + res);
return res;
}
/**
* 获取历史体现记录并解析分组处理
*
* @param pageNo
* @param pageSize
*/
private void startTixianRecordList() {
// 2、 读取假数据
String respOnse= getDataFromAsset("searchTixianrecordList.txt");
// 3、 初步解析
Gson gson = new Gson();
GetCashWithDrawRequestResponse info = gson.fromJson(response,
GetCashWithDrawRequestResponse.class);
if (info.getCashWithDrawRequestList() != null
&& info.getCashWithDrawRequestList().size() > 0) {
// 4、分组处理【重点】,重新拼装成分组控件所需的数据结构
transferForGroupList(info.getCashWithDrawRequestList());
tixianAdapter = new ZAdapter_tixian_recordHistory(
ZActivity_tixianHistory_groupList.this, listLast, listGroup);
pinnedlistView.setAdapter(tixianAdapter);
tixianAdapter.notifyDataSetInvalidated();
tixianAdapter.notifyDataSetChanged();
}
}
// 读取assets里的数据
public static byte[] getData(Context context, String fileUrl) {
byte[] data = null;
AssetManager am = context.getAssets();
try {
InputStream is = am.open(fileUrl);
byte[] buffer = new byte[256];
int length = 0;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
while ((length = is.read(buffer)) > 0) {
baos.write(buffer, 0, length);
}
data = baos.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}
return data;
}
@Override
public void onRefresh(PullToRefreshBase refreshView) {
Toast.makeText(ZActivity_tixianHistory_groupList.this, "on Refresh……",
Toast.LENGTH_SHORT).show();
}
}
项目下载地址:http://download.csdn.net/detail/u011084603/9370613