1.添加載入更多佈局 1_初始化和隱藏代碼在RefreshListView構造方法中調用 2_佈局文件refresh_listview_footer.xml 1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android= ...
1.添加載入更多佈局
1_初始化和隱藏代碼
在RefreshListView構造方法中調用
private void initFooterView(Context context) { View footerView = View.inflate(context, R.layout.refresh_listview_footer, null); //隱藏代碼 footerView.measure(0, 0); int footerViewHeight = footerView.getMeasuredHeight(); footerView.setPadding(0, -footerViewHeight, 0, 0); this.addFooterView(footerView); }
2_佈局文件refresh_listview_footer.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="wrap_content" 5 android:gravity="center" 6 android:orientation="horizontal" > 7 8 <ProgressBar 9 android:layout_margin="5dip" 10 android:layout_width="wrap_content" 11 android:layout_height="wrap_content" 12 android:indeterminateDrawable="@drawable/custom_progressbar" /> 13 14 <TextView 15 android:layout_marginLeft="10dip" 16 android:layout_width="wrap_content" 17 android:layout_height="wrap_content" 18 android:text="載入更多中..." 19 android:textColor="#ff0000" 20 android:textSize="25sp" /> 21 22 </LinearLayout>refresh_listview_footer.xml
2.拖動到底部的時候
1 /** 2 * 菜單頁面對應的新聞頁簽頁面 3 * 總共有12個 4 * @author Administrator 5 * 6 */ 7 public class TabMenuDetailPager extends MenuDetailBasePagerimplements OnPageChangeListener { 8 /** 9 * 新聞中心-新聞菜單對應的標簽對應的數據 10 */ 11 private NewCenterTag newCenterTag; 12 ....................... 13 /** 14 * 載入更多數據的URL 15 */ 16 private String moreUrl; 17 /** 18 * 是否載入更多數據中 19 */ 20 protected boolean isLoadingMore = false; 21 ................... 22 @Override 23 public View initView() { 24 View view = View.inflate(mActivity, R.layout.tab_detail, null); 25 //把View註入到XUtils框架中 26 ViewUtils.inject(this, view); 27 28 .......................... 29 30 //設置監聽下拉刷新 31 mListView.setOnRefreshListener(new OnRefreshListener() { 32 33 @Override 34 public void onPullDownRefresh() { 35 isPullDownRefreshing = true; 36 getDataFromNet(); 37 38 } 39 @Override 40 public void onLoadingMore() { 41 if(TextUtils.isEmpty(moreUrl)){ 42 Toast.makeText(mActivity, "沒有更多數據了", 1).show(); 43 mListView.onRefreshFinish(false); 44 }else{ 45 //有更多數據,要載入更多數據了 46 getMoreDataFromNet(); 47 } 48 } 49 }); 50 51 52 return view; 53 } 54 55 /** 56 * 載入更多數據 57 */ 58 protected void getMoreDataFromNet() { 59 60 HttpUtils httpUtils = new HttpUtils(); 61 httpUtils.send(HttpMethod.GET, moreUrl, new RequestCallBack<String>() { 62 @Override 63 public void onSuccess(ResponseInfo<String> responseInfo) { 64 System.out.println("載入更多數據成功:"+responseInfo.result); 65 mListView.onRefreshFinish(false); 66 isLoadingMore = true; 67 processData(responseInfo.result); 68 } 69 @Override 70 public void onFailure(HttpException error, String msg) { 71 mListView.onRefreshFinish(false); 72 System.out.println("載入更多數據失敗:"+ msg); 73 74 } 75 }); 76 77 78 } 79 80 /** 81 * 處理和解析json數據 82 * @param json 83 */ 84 protected void processData(String json) { 85 86 TabDetailBean bean = parserJson(json); 87 88 if(!isLoadingMore){ 89 System.out.println(bean.data.news.get(0).title); 90 topnews = bean.data.topnews; 91 92 //給ViewPager設置適配器 93 TabDetailAdapter adapter = new TabDetailAdapter(); 94 mViewPager.setAdapter(adapter); 95 96 97 // 把所有的View清除 98 ll_point_group.removeAllViews(); 99 for(int i=0;i<topnews.size();i++){ 100 View point = new View(mActivity); 101 LayoutParams params = new LayoutParams(5, 5) ; 102 point.setBackgroundResource(R.drawable.tab_detail_point_bg); 103 if(i!=0){ 104 params.leftMargin = 10; 105 } 106 point.setEnabled(false); 107 point.setLayoutParams(params); 108 109 ll_point_group.addView(point); 110 } 111 previousPointPosition = 0; 112 //設置預設的圖片描述和指示點 113 mtv_title_description.setText(topnews.get(previousPointPosition).title); 114 115 ll_point_group.getChildAt(previousPointPosition).setEnabled(true); 116 117 118 119 //設置頁面改變的監聽 120 mViewPager.setOnPageChangeListener(this); 121 122 //設置適配器和對應的數據 123 newsLists = bean.data.news; 124 listViewAdapter = new ListViewAdapter(); 125 mListView.setAdapter(listViewAdapter); 126 127 // mListView.addHeaderView(v) ;//把一個視圖一頭的方式添加到ListView中 128 129 }else{ 130 //把列表新聞取出來,在載入到以前的集合中,在刷新數據 131 isLoadingMore = false; 132 List<News>moreDataNews = bean.data.news; 133 newsLists.addAll(moreDataNews); 134 listViewAdapter.notifyDataSetChanged();//刷新數據 135 136 137 } 138 139 } 140 ................ 141 /** 142 * 用Gson開源項目解析json 143 * @param json 144 */ 145 private TabDetailBean parserJson(String json) { 146 Gson gson = new Gson(); 147 TabDetailBean bean = gson.fromJson(json, TabDetailBean.class); 148 moreUrl = bean.data.more; 149 if(TextUtils.isEmpty(moreUrl)){ 150 moreUrl = null; 151 }else{ 152 moreUrl = ConstantUtils.server_url+moreUrl; 153 } 154 155 return bean; 156 } 157 @Override 158 public void onPageScrollStateChanged(int arg0) { 159 // TODO Auto-generated method stub 160 161 } 162 @Override 163 public void onPageScrolled(int arg0, float arg1, int arg2) { 164 // TODO Auto-generated method stub 165 166 } 167 ............... 168 }TabMenuDetailPager
3.完整代碼
1 package com.atguigu.refreshlistview; 2 3 import android.content.Context; 4 import android.util.AttributeSet; 5 import android.view.MotionEvent; 6 import android.view.View; 7 import android.view.animation.Animation; 8 import android.view.animation.RotateAnimation; 9 import android.widget.AbsListView; 10 import android.widget.ImageView; 11 import android.widget.LinearLayout; 12 import android.widget.ListView; 13 import android.widget.ProgressBar; 14 import android.widget.TextView; 15 16 17 import java.text.SimpleDateFormat; 18 import java.util.Date; 19 20 /** 21 * 作用:自定義下拉刷新的ListView 22 */ 23 public class RefreshListview extends ListView { 24 /** 25 * 下拉刷新和頂部輪播圖 26 */ 27 private LinearLayout headerView; 28 29 /** 30 * 下拉刷新控制項 31 */ 32 private View ll_pull_down_refresh; 33 private ImageView iv_arrow; 34 private ProgressBar pb_status; 35 private TextView tv_status; 36 private TextView tv_time; 37 /** 38 * 下拉刷新控制項的高 39 */ 40 private int pullDownRefreshHeight; 41 42 /** 43 * 下拉刷新 44 */ 45 public static final int PULL_DOWN_REFRESH = 0; 46 47 /** 48 * 手鬆刷新 49 */ 50 public static final int RELEASE_REFRESH = 1; 51 52 53 /** 54 * 正在刷新 55 */ 56 public static final int REFRESHING = 2; 57 58 59 /** 60 * 當前狀態 61 */ 62 private int currentStatus = PULL_DOWN_REFRESH; 63 64 private Animation upAnimation; 65 private Animation downAnimation; 66 /** 67 * 載入更多的控制項 68 */ 69 private View footerView; 70 /** 71 * 載入更多控制項高 72 */ 73 private int footerViewHeight; 74 /** 75 * 是否已經載入更多 76 */ 77 private boolean isLoadMore = false; 78 /** 79 * 頂部輪播圖部分 80 */ 81 private View topNewsView; 82 /** 83 * ListView在Y軸上的坐標 84 */ 85 private int listViewOnScreenY = -1; 86 87 88 public RefreshListview(Context context) { 89 this(context, null); 90 } 91 92 public RefreshListview(Context context, AttributeSet attrs) { 93 this(context, attrs, 0); 94 } 95 96 public RefreshListview(Context context, AttributeSet attrs, int defStyleAttr) { 97 super(context, attrs, defStyleAttr); 98 initHeaderView(context); 99 initAnimation(); 100 initFooterView(context); 101 102 } 103 104 private void initFooterView(Context context) { 105 footerView = View.inflate(context, R.layout.refresh_footer, null); 106 footerView.measure(0, 0); 107 footerViewHeight = footerView.getMeasuredHeight(); 108 109 110 footerView.setPadding(0, -footerViewHeight, 0, 0); 111 112 //ListView添加footer 113 addFooterView(footerView); 114 115 116 //監聽ListView的滾動 117 setOnScrollListener(new MyOnScrollListener()); 118 } 119 120 /** 121 * 添加頂部輪播圖 122 * @param topNewsView 123 */ 124 public void addTopNewsView(View topNewsView) { 125 if(topNewsView != null){ 126 this.topNewsView =topNewsView; 127 headerView.addView(topNewsView); 128 } 129 130 131 } 132 133 class MyOnScrollListener implements OnScrollListener{ 134 135 @Override 136 public void onScrollStateChanged(AbsListView view, int scrollState) { 137 //當靜止或者慣性滾動的時候 138 if(scrollState ==OnScrollListener.SCROLL_STATE_IDLE||scrollState ==OnScrollListener.SCROLL_STATE_FLING){ 139 //並且是最後一條可見 140 if(getLastVisiblePosition()>=getCount()-1){ 141 142 //1.顯示載入更多佈局 143 footerView.setPadding(8,8,8,8); 144 //2.狀態改變 145 isLoadMore = true; 146 //3.回調介面 147 if(mOnRefreshListener != null){ 148 mOnRefreshListener.onLoadMore(); 149 } 150 } 151 } 152 153 154 } 155 156 @Override 157 public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { 158 159 } 160 } 161 162 163 private void initAnimation() { 164 upAnimation = new RotateAnimation(0, -180, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f); 165 upAnimation.setDuration(500); 166 upAnimation.setFillAfter(true); 167 168 downAnimation = new RotateAnimation(-180, -360, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f); 169 downAnimation.setDuration(500); 170 downAnimation.setFillAfter(true); 171 } 172 173 private void initHeaderView(Context context) { 174 headerView = (LinearLayout) View.inflate(context, R.layout.refresh_header, null); 175 //下拉刷新控制項 176 ll_pull_down_refresh = headerView.findViewById(R.id.ll_pull_down_refresh); 177 iv_arrow = (ImageView) headerView.findViewById(R.id.iv_arrow); 178 pb_status = (ProgressBar) headerView.findViewById(R.id.pb_status); 179 tv_status = (TextView) headerView.findViewById(R.id.tv_status); 180 tv_time = (TextView) headerView.findViewById(R.id.tv_time); 181 182 //測量 183 ll_pull_down_refresh.measure(0, 0); 184 pullDownRefreshHeight = ll_pull_down_refresh.getMeasuredHeight(); 185 186 //預設隱藏下拉刷新控制項 187 // View.setPadding(0,-控制項高,0,0);//完全隱藏 188 //View.setPadding(0, 0,0,0);//完全顯示 189 ll_pull_down_refresh.setPadding(0, -pullDownRefreshHeight, 0, 0); 190 191 //添加ListView的頭 192 addHeaderView(headerView); 193 } 194 195 private float startY = -1; 196 197 @Override 198 public boolean onTouchEvent(MotionEvent ev) { 199 switch (ev.getAction()) { 200 case MotionEvent.ACTION_DOWN: 201 //1.記錄起始坐標 202 startY = ev.getY(); 203 break; 204 case MotionEvent.ACTION_MOVE: 205 if (startY == -1) { 206 startY = ev.getY(); 207 } 208 209 //判斷頂部輪播圖是否完全顯示,只有完全顯示才會有下拉刷新 210 211 boolean isDisplayTopNews = isDisplayTopNews(); 212 if(!isDisplayTopNews){ 213 //載入更多 214 break; 215 } 216 217 218 //如果是正在刷新,就不讓再刷新了 219 if (currentStatus == REFRESHING) { 220 break; 221 } 222 //2.來到新的坐標 223 float endY = ev.getY(); 224 //3.記錄滑動的距離 225 float distanceY = endY - startY; 226 if (distanceY > 0) {//下拉 227 228 //int paddingTop = -控制項高 + distanceY; 229 int paddingTop = (int) (-pullDownRefreshHeight + distanceY); 230 231 if (paddingTop < 0 && currentStatus != PULL_DOWN_REFRESH) { 232 //下拉刷新狀態 233 currentStatus = PULL_DOWN_REFRESH; 234 //更新狀態 235 refreshViewState(); 236 237 } else if (paddingTop > 0 && currentStatus != RELEASE_REFRESH) { 238 //手鬆刷新狀態 239 currentStatus = RELEASE_REFRESH; 240 //更新狀態 241 refreshViewState(); 242 243 } 244 245 ll_pull_down_refresh.setPadding(0, paddingTop, 0, 0); 246 //View.setPadding(0,paddingTop,0,0);//動態的顯示下拉刷新控制項 247 } 248 break; 249 case MotionEvent.ACTION_UP: 250 startY = -1; 251 if (currentStatus == PULL_DOWN_REFRESH) { 252 // View.setPadding(0,-控制項高,0,0);//完全隱藏 253 ll_pull_down_refresh.setPadding(0, -pullDownRefreshHeight, 0, 0); 254 } else if (currentStatus == RELEASE_REFRESH) { 255 //設置狀態為正在刷新 256 currentStatus = REFRESHING; 257 258 refreshViewState(); 259 260 // View.setPadding(0,0,0,0);//完全顯示 261 ll_pull_down_refresh.setPadding(0, 0, 0, 0); 262 263 264 //回調介面 265 if (mOnRefreshListener != null) { 266 mOnRefreshListener.onPullDownRefresh(); 267 } 268 } 269 break; 270 271 } 272 return super.onTouchEvent(ev); 273 } 274 275 /** 276 * 判斷是否完全顯示頂部輪播圖 277 * 當ListView在屏幕上的Y軸坐標小於或者等於頂部輪播圖在Y軸的坐標的時候,頂部輪播圖完全顯示 278 * @return 279 */ 280 private boolean isDisplayTopNews() { 281 282 if(topNewsView != null){ 283 //1.得到ListView在屏幕上的坐標 284 int[] location = new int[2]; 285 if(listViewOnScreenY == -1){ 286 getLocationOnScreen(location); 287 listViewOnScreenY = location[1]; 288 } 289 290 //2.得到頂部輪播圖在屏幕上的坐標 291 topNewsView.getLocationOnScreen(location); 292 int topNewsViewOnScreenY = location[1]; 293 294 // if(listViewOnScreenY <= topNewsViewOnScreenY){ 295 // return true; 296 // }else{ 297 // return false; 298 // } 299 300 return listViewOnScreenY <= topNewsViewOnScreenY; 301 }else{ 302 return true; 303 } 304 305 } 306 307 private void refreshViewState() { 308 309 switch (currentStatus) { 310 case PULL_DOWN_REFRESH://下拉刷新狀態 311 iv_arrow.startAnimation(downAnimation); 312 tv_status.setText("下拉刷新..."); 313 break; 314 315 case RELEASE_REFRESH://手鬆刷新狀態 316 iv_arrow.startAnimation(upAnimation); 317 tv_status.setText("手鬆刷新..."); 318 break; 319 case REFRESHING://正在刷新狀態 320 tv_status.setText("正在刷新..."); 321 pb_status.setVisibility(VISIBLE); 322 iv_arrow.clearAnimation(); 323 iv_arrow.setVisibility(GONE); 324 break; 325 } 326 327 } 328 329 /** 330 * 當聯網成功和失敗的時候回調該方法 331 * 用戶刷新狀態的還原 332 * 333 * @param sucess 334 */ 335 public void onRefreshFinish(boolean sucess) { 336 if(isLoadMore){ 337 //載入更多 338 isLoadMore = false; 339 //隱藏載入更多佈局 340 footerView.setPadding(0,-footerViewHeight,0,0); 341 }else{ 342 //下拉刷新 343 tv_status.setText("下拉刷新..."); 344 currentStatus = PULL_DOWN_REFRESH; 345 iv_arrow.clearAnimation(); 346 pb_status.setVisibility(GONE); 347 iv_arrow.setVisibility(VISIBLE); 348