【FastDev4Android框架开发】Android 列表下拉刷新组件PullToRefreshListView使用(三)

jerry Android 2015年11月26日 收藏

(一):写在前面的话
接着上一篇继续更新,上一篇文章已经把FastDev4Android项目新增图片自动无限轮播,包括项目结构已经需要进行完善的功能,那么今天我们继续完善这个项目;今天我们会再项目添加下拉刷新组件以及组件实现讲解和使用基本方法;
(二):基本实现
这边我们采用继承Listview控件来扩展下拉刷新的功能,主要在listview的头部添加一个下拉刷新的view,然后监听OnScrollListener滚动接口和实现onTouchEvent方法来处理。进行下拉listview滑动到指定的高度,然后接口回调加载刷新方法即可。
这里写图片描述
效果如下:
这里写图片描述
(三):详细实现:
这边主要看几个重点地方,详细的代码到项目中查看即可
onTouchEvent处理方法

  1. /**
  2. * touch事件处理
  3. * @param event
  4. * @return
  5. */
  6. @Override
  7. public boolean onTouchEvent(MotionEvent event) {
  8. final int y = (int) event.getY();
  9. switch (event.getAction()) {
  10. case MotionEvent.ACTION_DOWN:
  11. mLastMotionY = y;
  12. break;
  13. case MotionEvent.ACTION_MOVE:
  14. int offsetY = (int) event.getY();
  15. int deltY = Math.round(offsetY - mLastMotionY);
  16. mLastMotionY = offsetY;
  17. if (getFirstVisiblePosition() == 0 && mRefreshState != REFRESHING) {
  18. deltY = deltY / 2;
  19. mRefreshOriginalTopPadding += deltY;
  20. if (mRefreshOriginalTopPadding < -mRefreshViewHeight) {
  21. mRefreshOriginalTopPadding = -mRefreshViewHeight;
  22. }
  23. resetHeaderPadding();
  24. }
  25. break;
  26. case MotionEvent.ACTION_UP:
  27. //当手指抬开得时候 进行判断下拉的距离 ,如果>=临界值,那么进行刷洗,否则回归原位
  28. if (!isVerticalScrollBarEnabled()) {
  29. setVerticalScrollBarEnabled(true);
  30. }
  31. if (getFirstVisiblePosition() == 0 && mRefreshState != REFRESHING) {
  32. if (mRefreshView.getBottom() >= mRefreshViewHeight
  33. && mRefreshState == RELEASE_TO_REFRESH) {
  34. //准备开始刷新
  35. prepareForRefresh();
  36. } else {
  37. // Abort refresh
  38. resetHeader();
  39. }
  40. }
  41. break;
  42. }
  43. return super.onTouchEvent(event);
  44. }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

onScrooll和onScrollStateChanged处理listview滑动过程中,实时改变头部view(pull view)上面的数据效果显示

  1. @Override
  2. public void onScroll(AbsListView view, int firstVisibleItem,
  3. int visibleItemCount, int totalItemCount) {
  4. if (mCurrentScrollState == SCROLL_STATE_TOUCH_SCROLL && mRefreshState != REFRESHING) {
  5. if (firstVisibleItem == 0) {
  6. if ((mRefreshView.getBottom() >= mRefreshViewHeight)
  7. && mRefreshState != RELEASE_TO_REFRESH) {
  8. mRefreshViewText.setText(R.string.pull_to_refresh_release_label_it);
  9. mRefreshViewImage.clearAnimation();
  10. mRefreshViewImage.startAnimation(mFlipAnimation);
  11. mRefreshState = RELEASE_TO_REFRESH;
  12. } else if (mRefreshView.getBottom() < mRefreshViewHeight
  13. && mRefreshState != PULL_TO_REFRESH) {
  14. mRefreshViewText.setText(R.string.pull_to_refresh_pull_label_it);
  15. mRefreshViewImage.clearAnimation();
  16. mRefreshViewImage.startAnimation(mReverseFlipAnimation);
  17. mRefreshState = PULL_TO_REFRESH;
  18. }
  19. }
  20. }
  21. if (mOnScrollListener != null) {
  22. mOnScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
  23. }
  24. }
  25. @Override
  26. public void onScrollStateChanged(AbsListView view, int scrollState) {
  27. mCurrentScrollState = scrollState;
  28. if (mOnScrollListener != null) {
  29. mOnScrollListener.onScrollStateChanged(view, scrollState);
  30. }
  31. }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

使用方法如下:

  1. package com.chinaztt.fda.test;
  2. import android.os.Bundle;
  3. import android.os.Handler;
  4. import android.os.Message;
  5. import android.text.Layout;
  6. import android.view.LayoutInflater;
  7. import android.view.View;
  8. import android.view.ViewGroup;
  9. import android.widget.AbsListView;
  10. import android.widget.AdapterView;
  11. import android.widget.BaseAdapter;
  12. import android.widget.LinearLayout;
  13. import android.widget.ProgressBar;
  14. import android.widget.TextView;
  15. import com.chinaztt.fda.ui.R;
  16. import com.chinaztt.fda.ui.base.BaseActivity;
  17. import com.chinaztt.fda.utils.UIUtils;
  18. import com.chinaztt.fda.widget.PullToRefreshListView;
  19. import java.util.ArrayList;
  20. import java.util.List;
  21. /**
  22. * 当前类注释:下拉刷新,上拉加载更多组件实例
  23. * 项目名:FastDev4Android
  24. * 包名:com.chinaztt.fda.test
  25. * 作者:江清清 on 15/10/23 11:25
  26. * 邮箱:jiangqqlmj@163.com
  27. * QQ: 781931404
  28. * 公司:江苏中天科技软件技术有限公司
  29. */
  30. public class PullListviewActivity extends BaseActivity{
  31. private PullToRefreshListView lv_pull_item;
  32. private PullAdapter mPullAdapter;
  33. private LayoutInflater mInflater;
  34. private List<String> mTitles;
  35. private View load_more;
  36. private TextView load_more_tv; // listview底部加载view 显示数据
  37. private ProgressBar load_more_progress; // listview底部加载view 显示进度
  38. private LinearLayout load_next_page_layout;
  39. private Handler newHandler=new Handler()
  40. {
  41. @Override
  42. public void handleMessage(Message msg) {
  43. super.handleMessage(msg);
  44. if(msg.what==1){
  45. refreshTitles();
  46. UIUtils.savePullToRefreshLastUpdateAt(lv_pull_item,UIUtils.DEMO_PULL_TIME_KEY);
  47. //刷新view
  48. mPullAdapter.notifyDataSetChanged();
  49. }else if(msg.what==2){
  50. moreTitles();
  51. //刷新view
  52. mPullAdapter.notifyDataSetChanged();
  53. showToastMsgShort("加载更多数据成功...");
  54. load_more_tv.setText("数据加载完成");
  55. }
  56. }
  57. };
  58. @Override
  59. protected void onCreate(Bundle savedInstanceState) {
  60. super.onCreate(savedInstanceState);
  61. setContentView(R.layout.pull_listview_layout);
  62. lv_pull_item=(PullToRefreshListView)this.findViewById(R.id.lv_pull_item);
  63. mInflater=getLayouInflater();
  64. //特别注意 里边的view的控件可以根据当前的状态 修改字符串信息
  65. load_more = mInflater.inflate(R.layout.load_more_footview_layout,
  66. null);
  67. load_more_tv = (TextView) load_more
  68. .findViewById(R.id.load_next_page_text);
  69. load_more_progress = (ProgressBar) load_more
  70. .findViewById(R.id.load_next_page_progress);
  71. load_next_page_layout = (LinearLayout) load_more
  72. .findViewById(R.id.load_next_page_layout);
  73. //listview添加尾部 上拉加载更多view
  74. lv_pull_item.addFooterView(load_more, null, false);
  75. load_more_tv.setText("上拉加载更多数据...");
  76. initTitles();
  77. //初始化 上次下拉刷新的时间
  78. UIUtils.setPullToRefreshLastUpdated(lv_pull_item,UIUtils.DEMO_PULL_TIME_KEY);
  79. mPullAdapter=new PullAdapter();
  80. lv_pull_item.setAdapter(mPullAdapter);
  81. //listview item点击事件处理
  82. lv_pull_item.setOnItemClickListener(new AdapterView.OnItemClickListener() {
  83. @Override
  84. public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
  85. int index = position++;
  86. showToastMsgShort("点击了第:" + index + "个item");
  87. }
  88. });
  89. //listview 开始下拉刷新回调函数
  90. lv_pull_item.setOnRefreshListener(new PullToRefreshListView.OnRefreshListener() {
  91. @Override
  92. public void onRefresh() {
  93. //进行加载数据
  94. new Thread(new Runnable() {
  95. @Override
  96. public void run() {
  97. try {
  98. Thread.sleep(5000);
  99. newHandler.sendEmptyMessage(1);
  100. } catch (InterruptedException e) {
  101. e.printStackTrace();
  102. }
  103. }
  104. }).start();
  105. }
  106. });
  107. //listview 滑动 进行上拉加载更多
  108. lv_pull_item.setOnScrollListener(new AbsListView.OnScrollListener() {
  109. @Override
  110. public void onScrollStateChanged(AbsListView view, int scrollState) {
  111. if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) {
  112. if (lv_pull_item.getLastVisiblePosition() == (lv_pull_item
  113. .getCount() - 1)) {
  114. load_more_tv.setText("正在加载最新数据....");
  115. //进行获取最新数据
  116. new Thread(new Runnable() {
  117. @Override
  118. public void run() {
  119. try {
  120. Thread.sleep(5000);
  121. newHandler.sendEmptyMessage(2);
  122. } catch (InterruptedException e) {
  123. e.printStackTrace();
  124. }
  125. }
  126. }).start();
  127. }
  128. }
  129. if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_FLING) {
  130. //正在滑动中,当前listview正在滑动 可以暂停图片加载器或者其他一些耗时操作
  131. } else {
  132. }
  133. }
  134. @Override
  135. public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
  136. }
  137. });
  138. }
  139. private void initTitles(){
  140. mTitles=new ArrayList<String>();
  141. for(int i=0;i<20;i++){
  142. int index=i+1;
  143. mTitles.add("当前是:"+index+"");
  144. }
  145. }
  146. private void refreshTitles(){
  147. List<String> newTitles=new ArrayList<String>();
  148. for(int i=0;i<5;i++){
  149. int index=i+1;
  150. newTitles.add("新数据是:"+index+"");
  151. }
  152. newTitles.addAll(mTitles);
  153. mTitles.removeAll(mTitles);
  154. mTitles.addAll(newTitles);
  155. }
  156. private void moreTitles(){
  157. List<String> newTitles=new ArrayList<String>();
  158. for(int i=0;i<8;i++){
  159. int index=i+1;
  160. newTitles.add("更多数据是:"+index+"");
  161. }
  162. mTitles.addAll(newTitles);
  163. }
  164. class PullAdapter extends BaseAdapter{
  165. @Override
  166. public int getCount() {
  167. return mTitles.size();
  168. }
  169. @Override
  170. public Object getItem(int position) {
  171. return mTitles.get(position);
  172. }
  173. @Override
  174. public long getItemId(int position) {
  175. return position;
  176. }
  177. @Override
  178. public View getView(int position, View convertView, ViewGroup parent) {
  179. Hondler _Hondler=null;
  180. if(convertView==null){
  181. _Hondler=new Hondler();
  182. convertView=mInflater.inflate(R.layout.lv_main_item,null);
  183. _Hondler.tv_item=(TextView)convertView.findViewById(R.id.tv_item);
  184. convertView.setTag(_Hondler);
  185. }else
  186. {
  187. _Hondler=(Hondler)convertView.getTag();
  188. }
  189. _Hondler.tv_item.setText(mTitles.get(position));
  190. return convertView;
  191. }
  192. }
  193. static class Hondler{
  194. TextView tv_item;
  195. }
  196. }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220

以上也是PullToRefreshListView的实现重点代码和基本使用效果,整个控件的功能实现代码如下:

  1. package com.chinaztt.fda.widget;
  2. import android.content.Context;
  3. import android.util.AttributeSet;
  4. import android.view.MotionEvent;
  5. import android.view.View;
  6. import android.view.View.OnClickListener;
  7. import android.view.animation.LinearInterpolator;
  8. import android.view.animation.RotateAnimation;
  9. import android.widget.AbsListView;
  10. import android.widget.AbsListView.OnScrollListener;
  11. import android.widget.ImageView;
  12. import android.widget.LinearLayout;
  13. import android.widget.ListView;
  14. import android.widget.ProgressBar;
  15. import android.widget.TextView;
  16. import com.chinaztt.fda.ui.R;
  17. import com.chinaztt.fda.utils.Log;
  18. /**
  19. * 当前类注释:下拉刷新,上拉加载更多组件
  20. * 项目名:FastDev4Android
  21. * 包名:com.chinaztt.fda.widget
  22. * 作者:江清清 on 15/10/23 13:32
  23. * 邮箱:jiangqqlmj@163.com
  24. * QQ: 781931404
  25. * 公司:江苏中天科技软件技术有限公司
  26. */
  27. public class PullToRefreshListView extends ListView implements OnScrollListener, OnClickListener {
  28. /**
  29. * 下拉状态
  30. */
  31. private static final int PULL_TO_REFRESH = 1; //下拉-默认为初始状态 准备下拉刷新
  32. private static final int RELEASE_TO_REFRESH = 2; //释放刷新
  33. private static final int REFRESHING = 3; //正在刷新
  34. private static final String TAG = "PullRefreshListView";
  35. private OnRefreshListener mOnRefreshListener;
  36. /**
  37. * 组件滑动监听器 scroll 当view在进行下拉滑动的时候,判断滑动的距离,
  38. * 如果达到可以进行刷新的临界点时候,回调当前接口中的方法
  39. * Listener that will receive notifications every time the list scrolls.
  40. */
  41. private OnScrollListener mOnScrollListener;
  42. //下拉刷新的的头部view
  43. private LinearLayout mRefreshView;
  44. private ImageView mRefreshViewImage;
  45. private ProgressBar mRefreshViewProgress;
  46. private TextView mRefreshViewText;
  47. private TextView mRefreshViewLastUpdated;
  48. private int mRefreshState;
  49. private int mCurrentScrollState;
  50. private RotateAnimation mFlipAnimation;
  51. private RotateAnimation mReverseFlipAnimation;
  52. private int mRefreshViewHeight;
  53. private int mRefreshOriginalTopPadding;
  54. private int mLastMotionY;
  55. public PullToRefreshListView(Context context) {
  56. super(context);
  57. init(context);
  58. }
  59. public PullToRefreshListView(Context context, AttributeSet attrs) {
  60. super(context, attrs);
  61. init(context);
  62. }
  63. private void init(Context context) {
  64. mFlipAnimation = new RotateAnimation(0, -180,
  65. RotateAnimation.RELATIVE_TO_SELF, 0.5f,
  66. RotateAnimation.RELATIVE_TO_SELF, 0.5f);
  67. mFlipAnimation.setInterpolator(new LinearInterpolator());
  68. mFlipAnimation.setDuration(250);
  69. mFlipAnimation.setFillAfter(true);
  70. mReverseFlipAnimation = new RotateAnimation(-180, 0,
  71. RotateAnimation.RELATIVE_TO_SELF, 0.5f,
  72. RotateAnimation.RELATIVE_TO_SELF, 0.5f);
  73. mReverseFlipAnimation.setInterpolator(new LinearInterpolator());
  74. mReverseFlipAnimation.setDuration(250);
  75. mReverseFlipAnimation.setFillAfter(true);
  76. mRefreshView = (LinearLayout) View.inflate(context, R.layout.pull_to_refresh_header, null);
  77. mRefreshViewText = (TextView) mRefreshView.findViewById(R.id.pull_to_refresh_text);
  78. mRefreshViewImage = (ImageView) mRefreshView.findViewById(R.id.pull_to_refresh_image);
  79. mRefreshViewProgress = (ProgressBar) mRefreshView.findViewById(R.id.pull_to_refresh_progress);
  80. mRefreshViewLastUpdated = (TextView) mRefreshView.findViewById(R.id.pull_to_refresh_updated_at);
  81. mRefreshState = PULL_TO_REFRESH;
  82. mRefreshViewImage.setMinimumHeight(50); //设置下拉最小的高度为50
  83. setFadingEdgeLength(0);
  84. setHeaderDividersEnabled(false);
  85. //把refreshview加入到listview的头部
  86. addHeaderView(mRefreshView);
  87. super.setOnScrollListener(this);
  88. mRefreshView.setOnClickListener(this);
  89. mRefreshView.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
  90. mRefreshViewHeight = mRefreshView.getMeasuredHeight();
  91. mRefreshOriginalTopPadding = -mRefreshViewHeight;
  92. resetHeaderPadding();
  93. }
  94. /**
  95. * Set the listener that will receive notifications every time the list scrolls.
  96. *
  97. * @param l The scroll listener.
  98. */
  99. @Override
  100. public void setOnScrollListener(OnScrollListener l) {
  101. mOnScrollListener = l;
  102. }
  103. /**
  104. * 注册listview下拉刷新回到接口
  105. * Register a callback to be invoked when this list should be refreshed.
  106. *
  107. * @param onRefreshListener The callback to run.
  108. */
  109. public void setOnRefreshListener(OnRefreshListener onRefreshListener) {
  110. mOnRefreshListener = onRefreshListener;
  111. }
  112. /**
  113. * 进行设置设置上一次更新的时候
  114. *
  115. * Set a text to represent when the list was last updated.
  116. * @param lastUpdated Last updated at.
  117. */
  118. public void setLastUpdated(CharSequence lastUpdated) {
  119. if (lastUpdated != null) {
  120. mRefreshViewLastUpdated.setVisibility(View.VISIBLE);
  121. mRefreshViewLastUpdated.setText(lastUpdated);
  122. } else {
  123. mRefreshViewLastUpdated.setVisibility(View.GONE);
  124. }
  125. }
  126. /**
  127. * touch事件处理
  128. * @param event
  129. * @return
  130. */
  131. @Override
  132. public boolean onTouchEvent(MotionEvent event) {
  133. final int y = (int) event.getY();
  134. switch (event.getAction()) {
  135. case MotionEvent.ACTION_DOWN:
  136. mLastMotionY = y;
  137. break;
  138. case MotionEvent.ACTION_MOVE:
  139. int offsetY = (int) event.getY();
  140. int deltY = Math.round(offsetY - mLastMotionY);
  141. mLastMotionY = offsetY;
  142. if (getFirstVisiblePosition() == 0 && mRefreshState != REFRESHING) {
  143. deltY = deltY / 2;
  144. mRefreshOriginalTopPadding += deltY;
  145. if (mRefreshOriginalTopPadding < -mRefreshViewHeight) {
  146. mRefreshOriginalTopPadding = -mRefreshViewHeight;
  147. }
  148. resetHeaderPadding();
  149. }
  150. break;
  151. case MotionEvent.ACTION_UP:
  152. //当手指抬开得时候 进行判断下拉的距离 ,如果>=临界值,那么进行刷洗,否则回归原位
  153. if (!isVerticalScrollBarEnabled()) {
  154. setVerticalScrollBarEnabled(true);
  155. }
  156. if (getFirstVisiblePosition() == 0 && mRefreshState != REFRESHING) {
  157. if (mRefreshView.getBottom() >= mRefreshViewHeight
  158. && mRefreshState == RELEASE_TO_REFRESH) {
  159. //准备开始刷新
  160. prepareForRefresh();
  161. } else {
  162. // Abort refresh
  163. resetHeader();
  164. }
  165. }
  166. break;
  167. }
  168. return super.onTouchEvent(event);
  169. }
  170. @Override
  171. public void onScroll(AbsListView view, int firstVisibleItem,
  172. int visibleItemCount, int totalItemCount) {
  173. if (mCurrentScrollState == SCROLL_STATE_TOUCH_SCROLL && mRefreshState != REFRESHING) {
  174. if (firstVisibleItem == 0) {
  175. if ((mRefreshView.getBottom() >= mRefreshViewHeight)
  176. && mRefreshState != RELEASE_TO_REFRESH) {
  177. mRefreshViewText.setText(R.string.pull_to_refresh_release_label_it);
  178. mRefreshViewImage.clearAnimation();
  179. mRefreshViewImage.startAnimation(mFlipAnimation);
  180. mRefreshState = RELEASE_TO_REFRESH;
  181. } else if (mRefreshView.getBottom() < mRefreshViewHeight
  182. && mRefreshState != PULL_TO_REFRESH) {
  183. mRefreshViewText.setText(R.string.pull_to_refresh_pull_label_it);
  184. mRefreshViewImage.clearAnimation();
  185. mRefreshViewImage.startAnimation(mReverseFlipAnimation);
  186. mRefreshState = PULL_TO_REFRESH;
  187. }
  188. }
  189. }
  190. if (mOnScrollListener != null) {
  191. mOnScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
  192. }
  193. }
  194. @Override
  195. public void onScrollStateChanged(AbsListView view, int scrollState) {
  196. mCurrentScrollState = scrollState;
  197. if (mOnScrollListener != null) {
  198. mOnScrollListener.onScrollStateChanged(view, scrollState);
  199. }
  200. }
  201. /**
  202. * Sets the header padding back to original size.
  203. */
  204. private void resetHeaderPadding() {
  205. mRefreshView.setPadding(
  206. mRefreshView.getPaddingLeft(),
  207. mRefreshOriginalTopPadding,
  208. mRefreshView.getPaddingRight(),
  209. mRefreshView.getPaddingBottom());
  210. }
  211. public void prepareForRefresh() {
  212. if (mRefreshState != REFRESHING) {
  213. mRefreshState = REFRESHING;
  214. mRefreshOriginalTopPadding = 0;
  215. resetHeaderPadding();
  216. mRefreshViewImage.clearAnimation();
  217. mRefreshViewImage.setVisibility(View.GONE);
  218. mRefreshViewProgress.setVisibility(View.VISIBLE);
  219. mRefreshViewText.setText(R.string.pull_to_refresh_refreshing_label_it);
  220. onRefresh();
  221. }
  222. }
  223. private void resetHeader() {
  224. mRefreshState = PULL_TO_REFRESH;
  225. mRefreshOriginalTopPadding = -mRefreshViewHeight;
  226. resetHeaderPadding();
  227. mRefreshViewImage.clearAnimation();
  228. mRefreshViewImage.setVisibility(View.VISIBLE);
  229. mRefreshViewProgress.setVisibility(View.GONE);
  230. mRefreshViewText.setText(R.string.pull_to_refresh_pull_label_it);
  231. }
  232. /**
  233. * 开始回调刷新
  234. */
  235. public void onRefresh() {
  236. Log.d(TAG, "onRefresh");
  237. if (mOnRefreshListener != null) {
  238. mOnRefreshListener.onRefresh();
  239. }
  240. }
  241. /**
  242. * Resets the list to a normal state after a refresh.
  243. */
  244. public void onRefreshComplete() {
  245. Log.d(TAG, "onRefreshComplete");
  246. resetHeader();
  247. }
  248. @Override
  249. public void onClick(View v) {
  250. Log.d(TAG, "onClick");
  251. }
  252. /**
  253. * Interface definition for a callback to be invoked when list should be
  254. * refreshed.
  255. */
  256. public interface OnRefreshListener {
  257. /**
  258. * Called when the list should be refreshed.
  259. * <p>
  260. * A call to {@link PullToRefreshListView #onRefreshComplete()} is
  261. * expected to indicate that the refresh has completed.
  262. */
  263. public void onRefresh();
  264. }
  265. }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309

核心实现类的代码就这些,其实整个文件读下来,实现起来也不难的吧~大家可以根据上面的代码可以修改定制成自己的控件都没问题的~希望可以帮助到大家,如果需要整个demo源代码可以去Github中下载整个项目:https://github.com/jiangqqlmj/FastDev4Android 同时欢迎大家star和fork整个开源快速开发框架项目~如果有什么意见和反馈,欢迎留言,必定第一时间回复。也欢迎有同样兴趣的童鞋加入到该项目中来,一起维护该项目。