Android 简易上下拉刷新

Android 简易上下拉刷新

以前忘记是在哪里听过一句话说,干android的必须要会上下拉刷新。

所以自己思索了一下,在加上网上的一些思路,完成了自己的简易上下拉刷新。

1.下拉刷新思路:

  当item的position为0的时候就可以执行下拉刷新,在滑动刷新过程中要经历4中状态:

  • NONE(ListView的初始状态).
  • PULL(ListView在下拉过程中,还没进入能松开刷新的状态)
  • REALSE(ListView进入到手指抬起后可刷新状态)
  • REFRESHING(ListView正在刷新状态)

然后根据状态的不同,对HeadView里面的内容进行改变即可

2.上拉加载更多

  监听ListView的滚动,来判断ListView滚动到哪里来进行在家更多。

3.数据获取:采用接口回调的方法来执行

部分代码:

  

  1 public class ScrollOverListViewReplica extends ListView implements
  2         OnScrollListener {
  3 
  4     private final static int RATIO = 2;
  5     private View headView;
  6     private ProgressBar headProgressBar;
  7     private ImageView headArrowImageView;
  8     private TextView headTipToLoad, headTipPullToRefresh;
  9     private int headViewHeight;
 10     // 定义下拉刷新时候的四种状态
 11     private final static int NONE = 0;
 12     private final static int PULL = 1;
 13     private final static int RELEASE = 2;
 14     private final static int REFRESHING = 3;
 15     private int startY;
 16     // 在按下的时候才记录startY的值
 17     private boolean isDown = true;
 18     // 当前状态值
 19     private int state;
 20     // 动画效果
 21     RotateAnimation mRotateAnimation, mRotateAnimation2;
 22     private int firstVisibleItem;
 23     private int scrollState;
 24     private boolean isback = false;
 25     private IOnRefreshListener mListener;
 26     // 脚部View
 27     private View footerView;
 28     private TextView footer_text;
 29     private ProgressBar footer_loading;
 30     // 倒数第几个开始加载更多选项
 31     private int bottomPosition;
 32     private int LastVisibleItemPosition;
 33     private int totalItemCount;
 34     private IonLoadMore mIonLoadMore;
 35 
 36     public ScrollOverListViewReplica(Context context) {
 37         super(context);
 38         initView(context);
 39 
 40     }
 41 
 42     public ScrollOverListViewReplica(Context context, AttributeSet attrs) {
 43         super(context, attrs);
 44         initView(context);
 45     }
 46 
 47     public ScrollOverListViewReplica(Context context, AttributeSet attrs,
 48             int defStyle) {
 49         super(context, attrs, defStyle);
 50         initView(context);
 51     }
 52 
 53     private void initView(Context context) {
 54         state = NONE;
 55         headView = LayoutInflater.from(context).inflate(R.layout.head_view,
 56                 null);
 57         headProgressBar = (ProgressBar) headView
 58                 .findViewById(R.id.head_progressBar);
 59         headArrowImageView = (ImageView) headView
 60                 .findViewById(R.id.head_arrowImageView);
 61         headTipPullToRefresh = (TextView) headView
 62                 .findViewById(R.id.head_tip_pull_to_refresh);
 63         headTipToLoad = (TextView) headView.findViewById(R.id.head_tip_to_load);
 64         // 对 headView 进行测量
 65         measure(headView);
 66         // 获取顶部的高度
 67         headViewHeight = headView.getMeasuredHeight();
 68         // 设置padding,初始化的时候不显示headView
 69         headView.setPadding(headView.getLeft(), -headViewHeight,
 70                 headView.getRight(), headView.getBottom());
 71         headView.invalidate();
 72         addHeaderView(headView);
 73         initAnimation();
 74         initListener();
 75         // 添加底部加载更多
 76         addFooterView(context);
 77 
 78     }
 79 
 80     private void addFooterView(Context context) {
 81         footerView = LayoutInflater.from(context).inflate(
 82                 R.layout.pulldown_footer, null);
 83         footer_text = (TextView) footerView
 84                 .findViewById(R.id.pulldown_footer_text);
 85         footer_loading = (ProgressBar) footerView
 86                 .findViewById(R.id.pulldown_footer_loading);
 87         footerView.setVisibility(View.GONE);
 88         addFooterView(footerView);
 89         // 判断数据是否填充了了整个ListView
 90 
 91     }
 92 
 93     private void initListener() {
 94         setOnScrollListener(this);
 95         // setOnScrollListener(new OnScrollListener() {
 96         //
 97         // @Override
 98         // public void onScrollStateChanged(AbsListView view, int scrollState) {
 99         // scrollState1 = scrollState;
100         // }
101         //
102         // @Override
103         // public void onScroll(AbsListView view, int firstVisibleItem,
104         // int visibleItemCount, int totalItemCount) {
105         // firstVisiblePosition = firstVisibleItem;
106         //
107         // }
108         // });
109     }
110 
111     // 初始化动画效果
112     private void initAnimation() {
113         mRotateAnimation = new RotateAnimation(0, -180,
114                 RotateAnimation.RELATIVE_TO_SELF, 0.5F,
115                 RotateAnimation.RELATIVE_TO_SELF, 0.5F);
116         mRotateAnimation.setInterpolator(new LinearInterpolator());
117         mRotateAnimation.setDuration(250);
118         mRotateAnimation.setFillAfter(true);
119 
120         mRotateAnimation2 = new RotateAnimation(-180, 0,
121                 RotateAnimation.RELATIVE_TO_SELF, 0.5F,
122                 RotateAnimation.RELATIVE_TO_SELF, 0.5F);
123         mRotateAnimation2.setInterpolator(new LinearInterpolator());
124         mRotateAnimation2.setDuration(200);
125         mRotateAnimation2.setFillAfter(true);
126 
127     }
128 
129     private void measure(View child) {
130         LinearLayout.LayoutParams lp = (android.widget.LinearLayout.LayoutParams) child
131                 .getLayoutParams();
132         if (lp == null) {
133             lp = new android.widget.LinearLayout.LayoutParams(
134                     LinearLayout.LayoutParams.MATCH_PARENT,
135                     LinearLayout.LayoutParams.WRAP_CONTENT);
136         }
137 
138         int headIWidthSpec = LinearLayout.getChildMeasureSpec(0, 0, lp.width);
139         int headHeight = lp.height;
140         int headHeightSpec;
141         if (headHeight > 0) {
142             headHeightSpec = MeasureSpec.makeMeasureSpec(headHeight,
143                     MeasureSpec.EXACTLY);
144         } else {
145             headHeightSpec = MeasureSpec.makeMeasureSpec(0,
146                     MeasureSpec.UNSPECIFIED);
147         }
148 
149         child.measure(headIWidthSpec, headHeightSpec);
150     }
151 
152     @Override
153     public boolean onTouchEvent(MotionEvent ev) {
154 
155         switch (ev.getAction()) {
156         case MotionEvent.ACTION_DOWN:
157 
158             if (firstVisibleItem == 0) {
159                 startY = (int) ev.getY();
160             }
161 
162             break;
163         case MotionEvent.ACTION_MOVE:
164 
165             // 在第一个条目在的时候才能下拉刷新
166             if (firstVisibleItem == 0) {
167                 motionMove(ev);
168             }
169 
170             int childrenCount = getChildCount();
171             if (childrenCount == 0) {
172                 return super.onTouchEvent(ev);
173             }
174 
175             break;
176         case MotionEvent.ACTION_UP:
177             if (state == RELEASE) {
178                 state = REFRESHING;
179                 changHeadViewByState();
180             } else {
181                 state = NONE;
182                 changHeadViewByState();
183             }
184 
185             break;
186         default:
187             break;
188         }
189 
190         return super.onTouchEvent(ev);
191     }
192 
193     private void motionMove(MotionEvent ev) {
194         // 记录滑动时候的Y的值
195         int moveY = (int) ev.getY();
196         // 获取滑动距离
197         int detal = (moveY - startY) / RATIO;
198         System.out.println("DETAL-->>" + detal);
199         switch (state) {
200         case NONE:
201 
202             if (detal > 0) {
203                 state = PULL;
204             }
205 
206             break;
207         case PULL:
208 
209             if (-headViewHeight + detal > 30) {
210                 state = RELEASE;
211                 isback = false;
212                 headArrowImageView.clearAnimation();
213                 headArrowImageView.startAnimation(mRotateAnimation);
214                 changHeadViewByState();
215             } else {
216                 state = NONE;
217                 changHeadViewByState();
218             }
219             headView.setPadding(0, -headViewHeight + detal, 0, 0);
220             break;
221         case RELEASE:
222             if (-headViewHeight + detal < 30
223                     && scrollState == OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
224                 state = PULL;
225                 // isback = true;
226                 headArrowImageView.clearAnimation();
227                 headArrowImageView.startAnimation(mRotateAnimation2);
228                 changHeadViewByState();
229             } else if (detal < 0) {
230                 state = NONE;
231                 changHeadViewByState();
232             }
233             headView.setPadding(0, -headViewHeight + detal, 0, 0);
234 
235             break;
236         }
237 
238     }
239 
240     // private ProgressBar headProgressBar;
241     // private ImageView headArrowImageView;
242     // private TextView headTipToLoad, headTipPullToRefresh;
243 
244     // 根据不同状态来改变headView
245     private void changHeadViewByState() {
246         switch (state) {
247         case NONE:
248             headProgressBar.setVisibility(View.GONE);
249             headArrowImageView.setVisibility(View.VISIBLE);
250             headTipToLoad.setVisibility(View.GONE);
251             headTipPullToRefresh.setVisibility(View.VISIBLE);
252             headTipPullToRefresh.setText("下拉即可刷新");
253             // headArrowImageView.clearAnimation();
254             headView.setPadding(0, -headViewHeight, 0, 0);
255             break;
256         case PULL:
257             headProgressBar.setVisibility(View.GONE);
258             headArrowImageView.setVisibility(View.VISIBLE);
259             headTipToLoad.setVisibility(View.GONE);
260             headTipPullToRefresh.setVisibility(View.VISIBLE);
261             headTipPullToRefresh.setText("下拉即可刷新");
262 
263             break;
264         case RELEASE:
265             headProgressBar.setVisibility(View.GONE);
266             headArrowImageView.setVisibility(View.VISIBLE);
267             headTipToLoad.setVisibility(View.GONE);
268             headTipPullToRefresh.setVisibility(View.VISIBLE);
269             headTipPullToRefresh.setText("松开即可刷新");
270             break;
271         case REFRESHING:
272             headProgressBar.setVisibility(View.VISIBLE);
273             headArrowImageView.setVisibility(View.GONE);
274             headTipToLoad.setVisibility(View.VISIBLE);
275             headTipPullToRefresh.setVisibility(View.GONE);
276             headView.setPadding(0, 0, 0, 0);
277             mListener.onRefresh();
278             break;
279         }
280     }
281 
282     public void completeRefresh() {
283         state = NONE;
284         headArrowImageView.clearAnimation();
285         headProgressBar.setVisibility(View.GONE);
286         headArrowImageView.setVisibility(View.VISIBLE);
287         headTipToLoad.setVisibility(View.GONE);
288         headTipPullToRefresh.setVisibility(View.VISIBLE);
289         headTipPullToRefresh.setText("下拉即可刷新");
290         headView.setPadding(0, -headViewHeight, 0, 0);
291     }
292 
293     public void setOnRefreshListener(IOnRefreshListener mListener) {
294         this.mListener = mListener;
295     }
296 
297     public interface IOnRefreshListener {
298         public void onRefresh();
299     }
300 
301     // 设置在倒数第几个的时候出发上拉加载更多
302 
303     public int getBottomPosition() {
304         return bottomPosition;
305     }
306 
307     public void setBottomPosition(int bottomPosition) {
308         this.bottomPosition = bottomPosition;
309     }
310 
311     @Override
312     public void onScrollStateChanged(AbsListView view, int scrollState) {
313 
314         this.scrollState = scrollState;
315 
316         if (scrollState != OnScrollListener.SCROLL_STATE_FLING) {
317             System.out.println("LastVisibleItemPosition-->>"
318                     + LastVisibleItemPosition);
319             if (LastVisibleItemPosition >= totalItemCount - bottomPosition) {
320                 footerView.setVisibility(View.VISIBLE);
321                 mIonLoadMore.onMore();
322             }
323 
324         }
325 
326     }
327 
328     public void setOnLoadMoreListener(IonLoadMore mIonLoadMore) {
329         this.mIonLoadMore = mIonLoadMore;
330     }
331 
332     public interface IonLoadMore {
333         public void onMore();
334     }
335 
336     @Override
337     public void onScroll(AbsListView view, int firstVisibleItem,
338             int visibleItemCount, int totalItemCount) {
339         this.firstVisibleItem = firstVisibleItem;
340         // 当前显示的最后一个Item的position
341         this.LastVisibleItemPosition = firstVisibleItem + visibleItemCount;
342         this.totalItemCount = totalItemCount;
343     }
344 
345 }


运行后效果是:

                              

因为是简易的上下拉刷新,bug还是有的后期完善。

源码下载地址:下载

posted @ 2015-04-22 20:45  perfect亮  阅读(332)  评论(0)    收藏  举报