分頁, 上拉重新整理、下拉載入。
阿新 • • 發佈:2018-12-04
一、自定義listview
package com.fragment.home; import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.view.animation.RotateAnimation; import android.widget.AbsListView; import android.widget.AbsListView.OnScrollListener; import android.widget.ImageView; import android.widget.ListView; import android.widget.ProgressBar; import android.widget.TextView; import java.text.SimpleDateFormat; import java.util.Date; import com.example.virtualaccount.R; public class CustomRefreshListView extends ListView implements OnScrollListener{ /** * 頭佈局 */ private View headerView; /** * 頭部佈局的高度 */ private int headerViewHeight; /** * 頭部旋轉的圖片 */ private ImageView iv_arrow; /** * 頭部下拉重新整理時狀態的描述 */ private TextView tv_state; /** * 下拉重新整理時間的顯示控制元件 */ private TextView tv_time; /** * 底部佈局 */ private View footerView; /** * 底部旋轉progressbar */ private ProgressBar pb_rotate; /** * 底部佈局的高度 */ private int footerViewHeight; /** * 按下時的Y座標 */ private int downY; private final int PULL_REFRESH = 0;//下拉重新整理的狀態 private final int RELEASE_REFRESH = 1;//鬆開重新整理的狀態 private final int REFRESHING = 2;//正在重新整理的狀態 /** * 當前下拉重新整理處於的狀態 */ private int currentState = PULL_REFRESH; /** * 頭部佈局在下拉重新整理改變時,圖示的動畫 */ private RotateAnimation upAnimation,downAnimation; /** * 當前是否在載入資料 */ private boolean isLoadingMore = false; public CustomRefreshListView(Context context) { this(context,null); } public CustomRefreshListView(Context context, AttributeSet attrs) { super(context, attrs); init(); } private void init(){ //設定滑動監聽 setOnScrollListener(this); //初始化頭佈局 initHeaderView(); //初始化頭佈局中圖示的旋轉動畫 initRotateAnimation(); //初始化為尾佈局 initFooterView(); } /** * 初始化headerView */ private void initHeaderView() { headerView = View.inflate(getContext(), R.layout.head_custom_listview, null); iv_arrow = (ImageView) headerView.findViewById(R.id.iv_arrow); pb_rotate = (ProgressBar) headerView.findViewById(R.id.pb_rotate); tv_state = (TextView) headerView.findViewById(R.id.tv_state); tv_time = (TextView) headerView.findViewById(R.id.tv_time); //測量headView的高度 headerView.measure(0, 0); //獲取高度,並儲存 headerViewHeight = headerView.getMeasuredHeight(); //設定paddingTop = -headerViewHeight;這樣,該控制元件被隱藏 headerView.setPadding(0, -headerViewHeight, 0, 0); //新增頭佈局 addHeaderView(headerView); } /** * 初始化旋轉動畫 */ private void initRotateAnimation() { upAnimation = new RotateAnimation(0, -180, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f); upAnimation.setDuration(300); upAnimation.setFillAfter(true); downAnimation = new RotateAnimation(-180, -360, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f); downAnimation.setDuration(300); downAnimation.setFillAfter(true); } //初始化底佈局,與頭佈局同理 private void initFooterView() { footerView = View.inflate(getContext(), R.layout.foot_custom_listview, null); footerView.measure(0, 0); footerViewHeight = footerView.getMeasuredHeight(); footerView.setPadding(0, -footerViewHeight, 0, 0); addFooterView(footerView); } @Override public boolean onTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: //獲取按下時y座標 downY = (int) ev.getY(); break; case MotionEvent.ACTION_MOVE: if(currentState==REFRESHING){ //如果當前處在滑動狀態,則不做處理 break; } //手指滑動偏移量 int deltaY = (int) (ev.getY() - downY); //獲取新的padding值 int paddingTop = -headerViewHeight + deltaY; if(paddingTop>-headerViewHeight && getFirstVisiblePosition()==0){ //向下滑,且處於頂部,設定padding值,該方法實現了頂佈局慢慢滑動顯現 headerView.setPadding(0, paddingTop, 0, 0); if(paddingTop>=0 && currentState==PULL_REFRESH){ //從下拉重新整理進入鬆開重新整理狀態 currentState = RELEASE_REFRESH; //重新整理頭佈局 refreshHeaderView(); }else if (paddingTop<0 && currentState==RELEASE_REFRESH) { //進入下拉重新整理狀態 currentState = PULL_REFRESH; refreshHeaderView(); } super.onTouchEvent(ev); return true;//攔截TouchMove,不讓listview處理該次move事件,會造成listview無法滑動 } break; case MotionEvent.ACTION_UP: if(currentState==PULL_REFRESH){ //仍處於下拉重新整理狀態,未滑動一定距離,不載入資料,隱藏headView headerView.setPadding(0, -headerViewHeight, 0, 0); }else if (currentState==RELEASE_REFRESH) { //滑倒一定距離,顯示無padding值的headcView headerView.setPadding(0, 0, 0, 0); //設定狀態為重新整理 currentState = REFRESHING; //重新整理頭部佈局 refreshHeaderView(); if(listener!=null){ //介面回撥載入資料 listener.onPullRefresh(); } } break; } return super.onTouchEvent(ev); } /** * 根據currentState來更新headerView */ private void refreshHeaderView(){ switch (currentState) { case PULL_REFRESH: tv_state.setText("下拉重新整理"); iv_arrow.startAnimation(downAnimation); break; case RELEASE_REFRESH: tv_state.setText("鬆開重新整理"); iv_arrow.startAnimation(upAnimation); break; case REFRESHING: iv_arrow.clearAnimation();//因為向上的旋轉動畫有可能沒有執行完 iv_arrow.setVisibility(View.INVISIBLE); pb_rotate.setVisibility(View.VISIBLE); tv_state.setText("正在重新整理..."); break; } } /** * 完成重新整理操作,重置狀態,在你獲取完資料並更新完adater之後,去在UI執行緒中呼叫該方法 */ public void completeRefresh(){ if(isLoadingMore){ //重置footerView狀態 footerView.setPadding(0, -footerViewHeight, 0, 0); isLoadingMore = false; }else { //重置headerView狀態 headerView.setPadding(0, -headerViewHeight, 0, 0); currentState = PULL_REFRESH; pb_rotate.setVisibility(View.INVISIBLE); iv_arrow.setVisibility(View.VISIBLE); tv_state.setText("下拉重新整理"); tv_time.setText("最後重新整理:"+getCurrentTime()); } } /** * 獲取當前系統時間,並格式化 * @return */ private String getCurrentTime(){ SimpleDateFormat format = new SimpleDateFormat("yy-MM-dd HH:mm:ss"); return format.format(new Date()); } private OnRefreshListener listener; public void setOnRefreshListener(OnRefreshListener listener){ this.listener = listener; } public interface OnRefreshListener{ void onPullRefresh(); void onLoadingMore(); } /** * SCROLL_STATE_IDLE:閒置狀態,就是靜止狀態 * SCROLL_STATE_TOUCH_SCROLL:手指觸控滑動,就是按著來滑動 * SCROLL_STATE_FLING:快速滑動後鬆開 */ @Override public void onScrollStateChanged(AbsListView view, int scrollState) { if(scrollState==OnScrollListener.SCROLL_STATE_IDLE && getLastVisiblePosition()==(getCount()-1) &&!isLoadingMore){ isLoadingMore = true; footerView.setPadding(0, 0, 0, 0);//顯示出footerView setSelection(getCount());//讓listview最後一條顯示出來 if(listener!=null){ listener.onLoadingMore(); } } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { // TODO Auto-generated method stub }
}
二、監聽listview
listview.setOnRefreshListener(new OnRefreshListener() { //上啦 重新整理,重新整理是把集合倒下序,最新的就顯示在最上面 @Override public void onPullRefresh() { // TODO Auto-generated method stub page+=1; FilterSelect("",page);//載入資料方法 用引數page來進行分頁和後臺協商好一頁傳幾條資料 listview.completeRefresh(); flag=true; } //下拉載入 載入延遲設定為1秒 @Override public void onLoadingMore() { listview.postDelayed(new Runnable() { @Override public void run() { page+=1; FilterSelect("",page); listview.completeRefresh(); } }, 1000L); } }); //傳送請求 填充資料 private void FilterSelect(String key,int page){ url=url+"&type="+key+"&page="+page; System.out.println(url); StringRequest param=new StringRequest(Method.GET,url,new Response.Listener<String>() { @Override public void onResponse(String response) { // TODO Auto-generated method stub Gson gson=new Gson(); root=gson.fromJson(response.toString(), GoodsRoot.class); if(root.status==1) { // data=root.data; // addData=data; if(flag){ List<GoodsDataBean> data=root.data; Collections.reverse(data); addData.addAll(data); } else addData.addAll(root.data); adapter=new GameDetailsAdapter(ProductDetails.this,addData); listview.setAdapter(adapter); } else Toast.makeText(ProductDetails.this, "暫無最新商品", Toast.LENGTH_SHORT).show(); } },null); requestdata.add(param); url=upurl; }