listView下拉刷新加载数据

来源:互联网 发布:淘宝企业店铺转个人 编辑:程序博客网 时间:2024/05/01 22:24

 在2月27号的时候,完成listView滑动刷新代码,昨天的时候,完成listView下拉刷新(sina微博Android客户端效果)效果的解析,其实在三个例子当中,感觉最好的应该是listView下拉刷新(sina微博Android客户端效果)里面的代码,今天进行第三个例子的解析,其中代码中添加了很多注释,所以文中代码和以前上传的代码注释方面会有很多不同,在文章的下面,会提供最新的代码下载。

         看这个代码的时候,刚开始一直是没有弄明白是怎么样运行的,后来通过不断的打log,大概弄了个明白,先给大家看下log:



          在下面,会把log语句的具体含义简单的说明一下。

          然后再把代码贴出来,按照log,一步一步跟踪,看它的实现过程:

[java] view plaincopyprint?
  1. public boolean onTouchEvent(MotionEvent event) {  
  2.         if (isRefreshable) {  
  3.             switch (event.getAction()) {  
  4.             case MotionEvent.ACTION_DOWN:  
  5.                 if (firstItemIndex == 0 && !isRecored) {  
  6.                     isRecored = true;  
  7.                     startY = (int) event.getY();  
  8.                     Log.v("@@@@@@""ACTION_DOWN 这是第  "+i+++"步" +1 );  
  9.                 }  
  10.                 break;  
  11.             case MotionEvent.ACTION_UP:  
  12.                 if (state != REFRESHING && state != LOADING) {  
  13.                     if (state == DONE) {  
  14.                     }  
  15.                     if (state == PULL_To_REFRESH) {  
  16.                         state = DONE;  
  17.                         Log.v("@@@@@@""ACTION_UP PULL_To_REFRESH and changeHeaderViewByState()" +  
  18.                                 " 这是第  "+i+++"步前"+2 );  
  19.                         changeHeaderViewByState();  
  20.                         Log.v("@@@@@@""ACTION_UP PULL_To_REFRESH and changeHeaderViewByState() " +  
  21.                                 "这是第  "+i+++"步后"+2 );  
  22.                     }  
  23.                     if (state == RELEASE_To_REFRESH) {  
  24.                         state = REFRESHING;  
  25.                         Log.v("@@@@@@""ACTION_UP RELEASE_To_REFRESH changeHeaderViewByState() " +  
  26.                                 "这是第  "+i+++"步" +3);  
  27.                         changeHeaderViewByState();                        
  28.                         onRefresh();  
  29.                         Log.v("@@@@@@""ACTION_UP RELEASE_To_REFRESH changeHeaderViewByState()" +  
  30.                                 " 这是第  "+i+++"步" +3);  
  31.                     }  
  32.                 }  
  33.                 isRecored = false;  
  34.                 isBack = false;  
  35.                 break;  
  36.             case MotionEvent.ACTION_MOVE:  
  37.                 int tempY = (int) event.getY();  
  38.                 if (!isRecored && firstItemIndex == 0) {  
  39.                     isRecored = true;  
  40.                     startY = tempY;  
  41.                     Log.v("@@@@@@""ACTION_MOVE 这是第  "+i+++"步" +4);  
  42.                 }  
  43.                 if (state != REFRESHING && isRecored && state != LOADING) {  
  44.                     if (state == RELEASE_To_REFRESH) {  
  45.                         setSelection(0);  
  46.                         if (((tempY - startY) / RATIO < headContentHeight)  
  47.                                 && (tempY - startY) > 0) {  
  48.                             state = PULL_To_REFRESH;  
  49.                             changeHeaderViewByState();  
  50.                             Log.v("@@@@@@""changeHeaderViewByState() 这是第  "+i+++"步"+5 );  
  51.                         }  
  52.                         else if (tempY - startY <= 0) {  
  53.                             state = DONE;  
  54.                             changeHeaderViewByState();  
  55.                             Log.v("@@@@@@""ACTION_MOVE RELEASE_To_REFRESH 2  changeHeaderViewByState " +  
  56.                                     "这是第  "+i+++"步" +6);  
  57.                         }  
  58.                     }  
  59.                     if (state == PULL_To_REFRESH) {  
  60.                         setSelection(0);  
  61.                         if ((tempY - startY) / RATIO >= headContentHeight) {  
  62.                             state = RELEASE_To_REFRESH;  
  63.                             isBack = true;  
  64.                             Log.v("@@@@@@""changeHeaderViewByState " +  
  65.                                     "这是第  "+i+++"步前"+7 );  
  66.                             changeHeaderViewByState();  
  67.                             Log.v("@@@@@@""changeHeaderViewByState " +  
  68.                                     "这是第  "+i+++"步后"+7 );  
  69.                         }  
  70.                         else if (tempY - startY <= 0) {  
  71.                             state = DONE;  
  72.                             changeHeaderViewByState();  
  73.                             Log.v("@@@@@@""ACTION_MOVE changeHeaderViewByState PULL_To_REFRESH 2" +  
  74.                                     " 这是第  "+i+++"步" +8);  
  75.                         }  
  76.                     }  
  77.                     if (state == DONE) {  
  78.                         if (tempY - startY > 0) {  
  79.                             state = PULL_To_REFRESH;  
  80.                             Log.v("@@@@@@""ACTION_MOVE DONE changeHeaderViewByState " +  
  81.                                     "这是第  "+i+++"步前" +9);  
  82.                             changeHeaderViewByState();  
  83.                             Log.v("@@@@@@""ACTION_MOVE DONE changeHeaderViewByState " +  
  84.                                     "这是第  "+i+++"步后" +9);  
  85.                         }  
  86.                     }  
  87.                     if (state == PULL_To_REFRESH) {  
  88.                         headView.setPadding(0, -1 * headContentHeight+(tempY - startY) / RATIO, 00);  
  89.                         Log.v("@@@@@@", -1 * headContentHeight+(tempY - startY) / RATIO+  
  90.                                 "ACTION_MOVE PULL_To_REFRESH 3  这是第  "+i+++"步"+10 );  
  91.                     }  
  92.                     if (state == RELEASE_To_REFRESH) {  
  93.                         headView.setPadding(0, (tempY - startY) / RATIO- headContentHeight, 00);  
  94.                         Log.v("@@@@@@""ACTION_MOVE PULL_To_REFRESH 4 这是第  "+i+++"步" +11);  
  95.                     }  
  96.                 }  
  97.                 break;  
  98.             }  
  99.         }  
  100.         return super.onTouchEvent(event);  
  101.     }  
  102.   
  103.     private void changeHeaderViewByState() {  
  104.         switch (state) {  
  105.         case RELEASE_To_REFRESH:  
  106.             arrowImageView.setVisibility(View.VISIBLE);  
  107.             progressBar.setVisibility(View.GONE);  
  108.             tipsTextview.setVisibility(View.VISIBLE);  
  109.             lastUpdatedTextView.setVisibility(View.VISIBLE);  
  110.             arrowImageView.clearAnimation();  
  111.             arrowImageView.startAnimation(animation);  
  112.             tipsTextview.setText("请释放 刷新");  
  113.             Log.v("@@@@@@""RELEASE_To_REFRESH 这是第  "+i+++"步"+12 +"请释放 刷新" );  
  114.             break;  
  115.         case PULL_To_REFRESH:  
  116.             progressBar.setVisibility(View.GONE);  
  117.             tipsTextview.setVisibility(View.VISIBLE);  
  118.             lastUpdatedTextView.setVisibility(View.VISIBLE);  
  119.             arrowImageView.clearAnimation();  
  120.             arrowImageView.setVisibility(View.VISIBLE);  
  121.             if (isBack) {  
  122.                 isBack = false;  
  123.                 arrowImageView.clearAnimation();  
  124.                 arrowImageView.startAnimation(reverseAnimation);  
  125.                 tipsTextview.setText("isBack  is true !!!");  
  126.             } else {  
  127.                 tipsTextview.setText("isBack  is false !!!");  
  128.             }  
  129.             Log.v("@@@@@@""PULL_To_REFRESH 这是第  "+i+++"步" +13+  
  130.                     "  changeHeaderViewByState()");  
  131.             break;  
  132.         case REFRESHING:  
  133.             headView.setPadding(0000);  
  134.             progressBar.setVisibility(View.VISIBLE);  
  135.             arrowImageView.clearAnimation();  
  136.             arrowImageView.setVisibility(View.GONE);  
  137.             tipsTextview.setText("正在加载中 ...REFRESHING");  
  138.             lastUpdatedTextView.setVisibility(View.VISIBLE);  
  139.             Log.v("@@@@@@""REFRESHING 这是第  "+i+++"步" +"正在加载中 ...REFRESHING");  
  140.             break;  
  141.         case DONE:  
  142.             headView.setPadding(0, -1 * headContentHeight, 00);  
  143.             progressBar.setVisibility(View.GONE);  
  144.             arrowImageView.clearAnimation();  
  145.             arrowImageView.setImageResource(R.drawable.arrow);  
  146.             tipsTextview.setText("已经加载完毕- DONE ");  
  147.             lastUpdatedTextView.setVisibility(View.VISIBLE);  
  148.             Log.v("@@@@@@""DONE 这是第  "+i+++"步" +"已经加载完毕- DONE ");  
  149.             break;  
  150.         }  
  151.     }  

     以上就是主要的功能代码,这个功能的实现,并没有在重写onScroll和onScrollStateChanged两个方法:
[java] view plaincopyprint?
  1. public void onScroll(AbsListView arg0, int firstVisiableItem, int arg2,  
  2.             int arg3) {  
  3.         firstItemIndex = firstVisiableItem;  
  4.     }  
  5.     public void onScrollStateChanged(AbsListView arg0, int arg1) {  
  6.     }  

主要就是通过onTouchEvent方法中根据不同的状态,进行不同的变化。

         先看下各个状态的定义:

[java] view plaincopyprint?
  1. //释放刷新   
  2.     private final static int RELEASE_To_REFRESH = 0;  
  3.     //下拉刷新   
  4.     private final static int PULL_To_REFRESH = 1;  
  5.     //正在刷新   
  6.     private final static int REFRESHING = 2;  
  7.     //刷新完成   
  8.     private final static int DONE = 3;  


        下面就开始通过log,跟踪代码的执行过程,首先执行的肯定是onTouchEvent里面的ACTION_DOWN

[java] view plaincopyprint?
  1. if (firstItemIndex == 0 && !isRecored) {  
  2.                     isRecored = true;  
  3.                     startY = (int) event.getY();  
  4.                     Log.v("@@@@@@""ACTION_DOWN 这是第  "+i+++"步" +1 );  
  5.                 }  
  6.                 break;  

在这里,简单的说明下,log语句的意思,这是第  "+i+++"步",是说明这是进行的第几步,最后面跟的数字是为了独特的标记该log。

        再往下看:

        

        我们在log中找到9,然后看一下,在ACTION_MOVE中,执行了这一步:

[java] view plaincopyprint?
  1. if (state == DONE) {  
  2.                         if (tempY - startY > 0) {  
  3.                             state = PULL_To_REFRESH;  
  4.                             Log.v("@@@@@@""ACTION_MOVE DONE changeHeaderViewByState " +  
  5.                                     "这是第  "+i+++"步前" +9);  
  6.                             changeHeaderViewByState();  
  7.                             Log.v("@@@@@@""ACTION_MOVE DONE changeHeaderViewByState " +  
  8.                                     "这是第  "+i+++"步后" +9);  
  9.                         }  
  10.                     }  
        为什么呢?因为在初始化的时候,把state初始化为Done,然后,
[java] view plaincopyprint?
  1. state = PULL_To_REFRESH;  
  2. changeHeaderViewByState();  
把state状态转换为PULL_To_REFRESH,然后运行changeHeaderViewByState方法里面

[java] view plaincopyprint?
  1. case PULL_To_REFRESH:  
  2.             progressBar.setVisibility(View.GONE);  
  3.             tipsTextview.setVisibility(View.VISIBLE);  
  4.             lastUpdatedTextView.setVisibility(View.VISIBLE);  
  5.             arrowImageView.clearAnimation();  
  6.             arrowImageView.setVisibility(View.VISIBLE);  
  7.             if (isBack) {  
  8.                 isBack = false;  
  9.                 arrowImageView.clearAnimation();  
  10.                 arrowImageView.startAnimation(reverseAnimation);  
  11.                 tipsTextview.setText("isBack  is true !!!");  
  12.             } else {  
  13.                 tipsTextview.setText("isBack  is false !!!");  
  14.             }  
  15.             Log.v("@@@@@@""PULL_To_REFRESH 这是第  "+i+++"步" +13+  
  16.                     "  changeHeaderViewByState()");  
  17.             break;  

在这里的各个控件的状态变化。state状态转换为PULL_To_REFRESH,代码继续向下进行


     所以会执行以下代码:

[java] view plaincopyprint?
  1. if (state == PULL_To_REFRESH) {  
  2.                         headView.setPadding(0, -1 * headContentHeight+(tempY - startY) / RATIO, 00);  
  3.                         Log.v("@@@@@@", -1 * headContentHeight+(tempY - startY) / RATIO+  
  4.                                 "ACTION_MOVE PULL_To_REFRESH 3  这是第  "+i+++"步"+10 );  
  5.                     }  

设置headView的各个距离,随后break,但是返回以后呢?还是继续进行ACTION_MOVE,由于state状态转换为PULL_To_REFRESH,所以会执行:

[java] view plaincopyprint?
  1. if (state == PULL_To_REFRESH) {  
  2.                         setSelection(0);  
  3.                         if ((tempY - startY) / RATIO >= headContentHeight) {  
  4.                             state = RELEASE_To_REFRESH;  
  5.                             isBack = true;  
  6.                             Log.v("@@@@@@""changeHeaderViewByState " +  
  7.                                     "这是第  "+i+++"步前"+7 );  
  8.                             changeHeaderViewByState();  
  9.                             Log.v("@@@@@@""changeHeaderViewByState " +  
  10.                                     "这是第  "+i+++"步后"+7 );  
  11.                         }  
  12.                         else if (tempY - startY <= 0) {  
  13.                             state = DONE;  
  14.                             changeHeaderViewByState();  
  15.                             Log.v("@@@@@@""ACTION_MOVE changeHeaderViewByState PULL_To_REFRESH 2" +  
  16.                                     " 这是第  "+i+++"步" +8);  
  17.                         }  
  18.                     }  

在本log里走的是if的第一分支,把state 的状态转化为RELEASE_To_REFRESH,然后执行changeHeaderViewByState里面:


[java] view plaincopyprint?
  1. case RELEASE_To_REFRESH:  
  2.             arrowImageView.setVisibility(View.VISIBLE);  
  3.             progressBar.setVisibility(View.GONE);  
  4.             tipsTextview.setVisibility(View.VISIBLE);  
  5.             lastUpdatedTextView.setVisibility(View.VISIBLE);  
  6.             arrowImageView.clearAnimation();  
  7.             arrowImageView.startAnimation(animation);  
  8.             tipsTextview.setText("请释放 刷新");  
  9.             Log.v("@@@@@@""RELEASE_To_REFRESH 这是第  "+i+++"步"+12 +"请释放 刷新" );  
  10.             break;  

如果继续向下拉,会执行ACTION_MOVE中的:

[java] view plaincopyprint?
  1. if (state == RELEASE_To_REFRESH) {  
  2.                         headView.setPadding(0, (tempY - startY) / RATIO- headContentHeight, 00);  
  3.                         Log.v("@@@@@@""ACTION_MOVE PULL_To_REFRESH 4 这是第  "+i+++"步" +11);  
  4.                     }  

继续看log:



进行完两个11以后,又会执行哪些代码呢?我们看到了3,然后我们找下这个log.

[java] view plaincopyprint?
  1. case MotionEvent.ACTION_UP:  
  2.                 if (state != REFRESHING && state != LOADING) {  
  3.                     if (state == DONE) {  
  4.                     }  
  5.                     if (state == PULL_To_REFRESH) {  
  6.                         state = DONE;  
  7.                         Log.v("@@@@@@""ACTION_UP PULL_To_REFRESH and changeHeaderViewByState()" +  
  8.                                 " 这是第  "+i+++"步前"+2 );  
  9.                         changeHeaderViewByState();  
  10.                         Log.v("@@@@@@""ACTION_UP PULL_To_REFRESH and changeHeaderViewByState() " +  
  11.                                 "这是第  "+i+++"步后"+2 );  
  12.                     }  
  13.                     if (state == RELEASE_To_REFRESH) {  
  14.                         state = REFRESHING;  
  15.                         Log.v("@@@@@@""ACTION_UP RELEASE_To_REFRESH changeHeaderViewByState() " +  
  16.                                 "这是第  "+i+++"步" +3);  
  17.                         changeHeaderViewByState();                        
  18.                         onRefresh();  
  19.                         Log.v("@@@@@@""ACTION_UP RELEASE_To_REFRESH changeHeaderViewByState()" +  
  20.                                 " 这是第  "+i+++"步" +3);  
  21.                     }  
  22.                 }  
  23.                 isRecored = false;  
  24.                 isBack = false;  
  25.                 break;  

就是当手指送开的时候,执行到了ACTION_UP,因为state 的状态转化为RELEASE_To_REFRESH,里面调用了

[java] view plaincopyprint?
  1. case RELEASE_To_REFRESH:  
  2.             arrowImageView.setVisibility(View.VISIBLE);  
  3.             progressBar.setVisibility(View.GONE);  
  4.             tipsTextview.setVisibility(View.VISIBLE);  
  5.             lastUpdatedTextView.setVisibility(View.VISIBLE);  
  6.             arrowImageView.clearAnimation();  
  7.             arrowImageView.startAnimation(animation);  
  8.             tipsTextview.setText("请释放 刷新");  
  9.             Log.v("@@@@@@""RELEASE_To_REFRESH 这是第  "+i+++"步"+12 +"请释放 刷新" );  
  10.             break;  

    和onRefresh方法,和listView下拉刷新(sina微博Android客户端效果)一样,这是个回调方法。

    最后调用 onRefreshComplete刷新完成方法:

[java] view plaincopyprint?
  1. public void onRefreshComplete() {  
  2.         state = DONE;  
  3.         lastUpdatedTextView.setText("已加载完成: " + new Date().toLocaleString());  
  4.         changeHeaderViewByState();  
  5.         Log.v("@@@@@@""onRefreshComplete() 被调用。。。");  
  6.     }  

最后程序运行结果如下:

下拉

 


继续下拉



手指松开


原创粉丝点击