listView下拉刷新2

来源:互联网 发布:php集成化安装包 编辑:程序博客网 时间:2024/04/30 18:40
 

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

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

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

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

public boolean onTouchEvent(MotionEvent event) {
        if(isRefreshable) {
            switch(event.getAction()) {
            caseMotionEvent.ACTION_DOWN:
                if(firstItemIndex ==0&& !isRecored) {
                    isRecored =true;
                    startY = (int) event.getY();
                    Log.v("@@@@@@","ACTION_DOWN 这是第  "+i+++"步"+1);
                }
                break;
            caseMotionEvent.ACTION_UP:
                if(state != REFRESHING && state != LOADING) {
                    if(state == DONE) {
                    }
                    if(state == PULL_To_REFRESH) {
                        state = DONE;
                        Log.v("@@@@@@","ACTION_UP PULL_To_REFRESH and changeHeaderViewByState()"+
                                " 这是第  "+i+++"步前"+2);
                        changeHeaderViewByState();
                        Log.v("@@@@@@","ACTION_UP PULL_To_REFRESH and changeHeaderViewByState() "+
                                "这是第  "+i+++"步后"+2);
                    }
                    if(state == RELEASE_To_REFRESH) {
                        state = REFRESHING;
                        Log.v("@@@@@@","ACTION_UP RELEASE_To_REFRESH changeHeaderViewByState() "+
                                "这是第  "+i+++"步"+3);
                        changeHeaderViewByState();                      
                        onRefresh();
                        Log.v("@@@@@@","ACTION_UP RELEASE_To_REFRESH changeHeaderViewByState()"+
                                " 这是第  "+i+++"步"+3);
                    }
                }
                isRecored =false;
                isBack =false;
                break;
            caseMotionEvent.ACTION_MOVE:
                inttempY = (int) event.getY();
                if(!isRecored && firstItemIndex ==0) {
                    isRecored =true;
                    startY = tempY;
                    Log.v("@@@@@@","ACTION_MOVE 这是第  "+i+++"步"+4);
                }
                if(state != REFRESHING && isRecored && state != LOADING) {
                    if(state == RELEASE_To_REFRESH) {
                        setSelection(0);
                        if(((tempY - startY) / RATIO < headContentHeight)
                                && (tempY - startY) >0) {
                            state = PULL_To_REFRESH;
                            changeHeaderViewByState();
                            Log.v("@@@@@@","changeHeaderViewByState() 这是第  "+i+++"步"+5);
                        }
                        elseif(tempY - startY <= 0) {
                            state = DONE;
                            changeHeaderViewByState();
                            Log.v("@@@@@@","ACTION_MOVE RELEASE_To_REFRESH 2  changeHeaderViewByState "+
                                    "这是第  "+i+++"步"+6);
                        }
                    }
                    if(state == PULL_To_REFRESH) {
                        setSelection(0);
                        if((tempY - startY) / RATIO >= headContentHeight) {
                            state = RELEASE_To_REFRESH;
                            isBack =true;
                            Log.v("@@@@@@","changeHeaderViewByState " +
                                    "这是第  "+i+++"步前"+7);
                            changeHeaderViewByState();
                            Log.v("@@@@@@","changeHeaderViewByState " +
                                    "这是第  "+i+++"步后"+7);
                        }
                        elseif(tempY - startY <= 0) {
                            state = DONE;
                            changeHeaderViewByState();
                            Log.v("@@@@@@","ACTION_MOVE changeHeaderViewByState PULL_To_REFRESH 2"+
                                    " 这是第  "+i+++"步"+8);
                        }
                    }
                    if(state == DONE) {
                        if(tempY - startY >0) {
                            state = PULL_To_REFRESH;
                            Log.v("@@@@@@","ACTION_MOVE DONE changeHeaderViewByState "+
                                    "这是第  "+i+++"步前"+9);
                            changeHeaderViewByState();
                            Log.v("@@@@@@","ACTION_MOVE DONE changeHeaderViewByState "+
                                    "这是第  "+i+++"步后"+9);
                        }
                    }
                    if(state == PULL_To_REFRESH) {
                        headView.setPadding(0, -1* headContentHeight+(tempY - startY) / RATIO, 0,0);
                        Log.v("@@@@@@", -1* headContentHeight+(tempY - startY) / RATIO+
                                "ACTION_MOVE PULL_To_REFRESH 3  这是第  "+i+++"步"+10);
                    }
                    if(state == RELEASE_To_REFRESH) {
                        headView.setPadding(0, (tempY - startY) / RATIO- headContentHeight,0,0);
                        Log.v("@@@@@@","ACTION_MOVE PULL_To_REFRESH 4 这是第  "+i+++"步"+11);
                    }
                }
                break;
            }
        }
        returnsuper.onTouchEvent(event);
    }
  
    privatevoidchangeHeaderViewByState() {
        switch(state) {
        caseRELEASE_To_REFRESH:
            arrowImageView.setVisibility(View.VISIBLE);
            progressBar.setVisibility(View.GONE);
            tipsTextview.setVisibility(View.VISIBLE);
            lastUpdatedTextView.setVisibility(View.VISIBLE);
            arrowImageView.clearAnimation();
            arrowImageView.startAnimation(animation);
            tipsTextview.setText("请释放 刷新");
            Log.v("@@@@@@","RELEASE_To_REFRESH 这是第  "+i+++"步"+12+"请释放 刷新" );
            break;
        casePULL_To_REFRESH:
            progressBar.setVisibility(View.GONE);
            tipsTextview.setVisibility(View.VISIBLE);
            lastUpdatedTextView.setVisibility(View.VISIBLE);
            arrowImageView.clearAnimation();
            arrowImageView.setVisibility(View.VISIBLE);
            if(isBack) {
                isBack =false;
                arrowImageView.clearAnimation();
                arrowImageView.startAnimation(reverseAnimation);
                tipsTextview.setText("isBack  is true !!!");
            }else{
                tipsTextview.setText("isBack  is false !!!");
            }
            Log.v("@@@@@@","PULL_To_REFRESH 这是第  "+i+++"步"+13+
                    "  changeHeaderViewByState()");
            break;
        caseREFRESHING:
            headView.setPadding(0,0,0,0);
            progressBar.setVisibility(View.VISIBLE);
            arrowImageView.clearAnimation();
            arrowImageView.setVisibility(View.GONE);
            tipsTextview.setText("正在加载中 ...REFRESHING");
            lastUpdatedTextView.setVisibility(View.VISIBLE);
            Log.v("@@@@@@","REFRESHING 这是第  "+i+++"步"+"正在加载中 ...REFRESHING");
            break;
        caseDONE:
            headView.setPadding(0, -1* headContentHeight, 0,0);
            progressBar.setVisibility(View.GONE);
            arrowImageView.clearAnimation();
            arrowImageView.setImageResource(R.drawable.arrow);
            tipsTextview.setText("已经加载完毕- DONE ");
            lastUpdatedTextView.setVisibility(View.VISIBLE);
            Log.v("@@@@@@","DONE 这是第  "+i+++"步"+"已经加载完毕- DONE ");
            break;
        }
    }
以上就是主要的功能代码,这个功能的实现,并没有在重写onScroll和onScrollStateChanged两个方法:

1
2
3
4
5
6
public void onScroll(AbsListView arg0, intfirstVisiableItem,intarg2,
            intarg3) {
        firstItemIndex = firstVisiableItem;
    }
    publicvoidonScrollStateChanged(AbsListView arg0,intarg1) {
    }

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

先看下各个状态的定义:

1
2
3
4
5
6
7
8
//释放刷新
    privatefinalstatic int RELEASE_To_REFRESH = 0;
    //下拉刷新
    privatefinalstatic int PULL_To_REFRESH = 1;
    //正在刷新
    privatefinalstatic int REFRESHING = 2;
    //刷新完成
    privatefinalstatic int DONE = 3;

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

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

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

再往下看:

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

1
2
3
4
5
6
7
8
9
10
if (state == DONE) {
                        if(tempY - startY >0) {
                            state = PULL_To_REFRESH;
                            Log.v("@@@@@@","ACTION_MOVE DONE changeHeaderViewByState "+
                                    "这是第  "+i+++"步前"+9);
                            changeHeaderViewByState();
                            Log.v("@@@@@@","ACTION_MOVE DONE changeHeaderViewByState "+
                                    "这是第  "+i+++"步后"+9);
                        }
                    }

为什么呢?因为在初始化的时候,把state初始化为Done,然后,

1
2
state = PULL_To_REFRESH;
changeHeaderViewByState();

把state状态转换为PULL_To_REFRESH,然后运行changeHeaderViewByState方法里面的

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

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

所以会执行以下代码:

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

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

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

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

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

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

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

继续看log:


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

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
case MotionEvent.ACTION_UP:
                if(state != REFRESHING && state != LOADING) {
                    if(state == DONE) {
                    }
                    if(state == PULL_To_REFRESH) {
                        state = DONE;
                        Log.v("@@@@@@","ACTION_UP PULL_To_REFRESH and changeHeaderViewByState()"+
                                " 这是第  "+i+++"步前"+2);
                        changeHeaderViewByState();
                        Log.v("@@@@@@","ACTION_UP PULL_To_REFRESH and changeHeaderViewByState() "+
                                "这是第  "+i+++"步后"+2);
                    }
                    if(state == RELEASE_To_REFRESH) {
                        state = REFRESHING;
                        Log.v("@@@@@@","ACTION_UP RELEASE_To_REFRESH changeHeaderViewByState() "+
                                "这是第  "+i+++"步"+3);
                        changeHeaderViewByState();                      
                        onRefresh();
                        Log.v("@@@@@@","ACTION_UP RELEASE_To_REFRESH changeHeaderViewByState()"+
                                " 这是第  "+i+++"步"+3);
                    }
                }
                isRecored =false;
                isBack =false;
                break;

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

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

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

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

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

最后程序运行结果如下:

下拉

 

继续下拉


手指松开


最后,是源代码下载地址:http://download.csdn.net/detail/aomandeshangxiao/4119893 大笑

来源:http://blog.csdn.net/aomandeshangxiao/article/details/7328045

 

原创粉丝点击