Android分組列表懸停顯示,分組listView懸停效果,帶下拉重新整理和上拉載入更多
分組列表,帶下拉重新整理和上拉載入更多【專案地址在文章最後!!】
效果圖:
實現過程,借鑑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_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:divider="@color/view_line"
android:dividerHeight="1dp"
ptr:ptrHeaderTextColor="@android:color/darker_gray" >
</com.handmark.pulltorefresh.library.PullToRefreshUpLoadPinnedHeaderListView>
二、主工程目錄結構:
activity中
實現下拉重新整理和上拉載入需要在activity呼叫中繼承如下兩個介面:
OnLoadingMoreLinstenerInPull, OnRefreshListener
呼叫過程完成程式碼【讀取assets中假資料進行顯示,主要難點是解析資料進行重組成控制元件所需要的資料結構。。下面程式碼已經列出解析過程。可以直接用】:
/**
* 帶分組功能的listView,待上拉載入和下拉重新整理功能
*
* @author zp
*
* 2015年11月22日
*/
public class ZActivity_tixianHistory_groupList extends Activity implements
OnLoadingMoreLinstenerInPull, OnRefreshListener<ListView>,
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<String> listGroup = new ArrayList<String>();// 組容器。存放所有的組,用於listView引數
List<ZModel_tixian_record> listLast = new ArrayList<ZModel_tixian_record>();// 存放分好組的資料模型,用於顯示到listview
ZModel_tixian_record model = null;// 實體類物件
List<CashWithDrawRequestList> 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<ElementCashWithDrawRequestList> 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<ZModel_tixian_record.CashWithDrawRequestList>();
// 組和子列表分開儲存
for (int j = 0; j < list_cash.size(); 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<ListView> refreshView) {
Toast.makeText(ZActivity_tixianHistory_groupList.this, "on Refresh……",
Toast.LENGTH_SHORT).show();
}
}