在下拉错误刷新列表视图的android [英] Error in pull down to refresh list view android

查看:182
本文介绍了在下拉错误刷新列表视图的android的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的功能拉下使用此 chrisbanes库刷新
但是,当我试图在我的XML文件中导入这个小部件
它显示我下面error.Please帮助我如何解决这个问题。
错误:

  com.handmark.pulltorefresh.library.PullToRefreshListView失败的实例。


解决方案

我肯定会看看克里斯巴内斯实施拉来刷新的。他的code不仅包括ListView的这种互动式的,也GridView和web视图。

尤其是后者将是你的情况的兴趣,因为它是为不使用适配器对其内容的视图的示例实现拉至刷新的。如果你看一下源$ C ​​$ C,你会看到每一个具体拉至refreh视图诅咒项目从一个普通的PullToRefreshBase,包含大部分逻辑的动画和清凉延伸。具有基类的好处是,做同样的事情对于任何其它类型的图,例如一个TextView,应该是pretty简单。

这种方法的唯一缺点是实施对其他观点的包装,这意味着你必须写一些额外的线条来获得实际的看法。因此,这不是一个完整的简易替换。然而,它的功能和特性远远超过些许不便。

编辑:

看看下面code我已实施

您主要的Java文件:

  PullToRefreshListView列表视图;列表视图=(PullToRefreshListView)findViewById(R.id.airpost_listView);    listview.setOnRefreshListener(新OnRefreshListener(){
        公共无效onRefresh(){
            // TODO自动生成方法存根
            新的getPost()执行(); // AsyncTask的,你可以把你的逻辑何时调用列表视图获取新数据或让它成为像以前一样
        }
    });

列表视图在XML文件中定义的:

 <的LinearLayout
        机器人:layout_width =FILL_PARENT
        机器人:layout_height =FILL_PARENT
        机器人:背景=@绘制/ bhavesh
        机器人:填充=5DP>        < com.FlightMate.AirpostTab.PullToRefreshListView
            机器人:ID =@ + ID / airpost_listView
            机器人:layout_width =FILL_PARENT
            机器人:layout_height =FILL_PARENT
            机器人:背景=#FFFFFF
            机器人:cacheColorHint =@机器人:彩色/透明
            机器人:分=#00000000/>
    < / LinearLayout中>

这里是PullToRefreshListView:

 包com.FlightMate.AirpostTab;进口android.content.Context;
进口android.util.AttributeSet;
进口android.widget.ListView;公共类PullToRefreshListView扩展PullToRefreshBase<&的ListView GT; {    公共PullToRefreshListView(上下文的背景下){
        超级(上下文);
    }    公共PullToRefreshListView(上下文的背景下,ATTRS的AttributeSet){
        超(背景下,ATTRS);
    }    @覆盖
    保护最后的ListView createAdapterView(上下文的背景下,
            AttributeSet中的ATTRS){
        ListView控件LV =新的ListView(背景下,ATTRS);
        //将它设置为这个这样就可以在ListActivity / ListFragment使用        lv.setId(android.R.id.list);
        返回LV;
    }}

这里是PullToRefreshBase:

 包com.FlightMate.AirpostTab;进口android.content.Context;
进口android.content.res.TypedArray;
进口android.graphics.Color;
进口android.os.Handler;
进口android.util.AttributeSet;
进口android.view.MotionEvent;
进口android.view.View;
进口android.view.View.OnTouchListener;
进口android.view.ViewGroup;
进口android.view.animation.AccelerateDecelerateInterpolator;
进口android.view.animation.Interpolator;
进口android.widget.AbsListView;
进口android.widget.AbsListView.OnScrollListener;
进口android.widget.LinearLayout;进口com.FlightMate.R;公共抽象类PullToRefreshBase<吨延伸AbsListView>扩展
        的LinearLayout实现OnTouchListener,OnScrollListener {    私人final类SmoothScrollRunnable实现Runnable {        静态最终诠释ANIMATION_DURATION_MS = 190;
        静态最终诠释ANIMATION_FPS =六十分之千;        私人最终插补插补;
        私人最终诠释scrollToY;
        私人最终诠释scrollFromY;
        私人最终处理程序处理程序;        私人布尔continueRunning = TRUE;
        私人长期STARTTIME = -1;
        私人INT currentY = -1;        公共SmoothScrollRunnable(处理程序处理,诠释弗罗米,诠释玩具){
            this.handler =处理程序;
            this.scrollFromY =弗罗米;
            this.scrollToY =玩具;
            this.interpolator =新AccelerateDecelerateInterpolator();
        }        // @覆盖
        公共无效的run(){            / **
             *仅设定的startTime如果这是我们第一次开始,否则
             *实际计算在Y三角洲
             * /
            如果(==的startTime -1){
                STARTTIME = System.currentTimeMillis的();
            }其他{                / **
                 *我们做做所有的计算长,以减少软件浮动
                 *计算。我们使用1000,因为它为我们提供了良好的精度和
                 *小舍入误差
                 * /
                长normalizedTime =(1000 *(System.currentTimeMillis的() - startTime时))
                        / ANIMATION_DURATION_MS;
                normalizedTime = Math.max(Math.min(normalizedTime,1000),0);                最终诠释DELTAY =数学
                        .round((scrollFromY - scrollToY)
                                *插值
                                        .getInterpolation(normalizedTime / 1000F));
                this.currentY = scrollFromY - DELTAY;
                setHeaderScroll(currentY);
            }            //如果我们在对象物Y不是,那就继续吧...
            如果(continueRunning&安培;&安培;!scrollToY = currentY){
                handler.postDelayed(这一点,ANIMATION_FPS);
            }
        }        公共无效停止(){
            this.continueRunning = FALSE;
            this.handler.removeCallbacks(本);
        }
    };    // ================================================ ===========
    //常量
    // ================================================ ===========    静态最终诠释PULL_TO_REFRESH = 0;
    静态最终诠释RELEASE_TO_REFRESH = PULL_TO_REFRESH + 1;
    静态最终诠释REFRESHING = RELEASE_TO_REFRESH + 1;
    静态最终诠释EVENT_COUNT = 3;    公共静态最终诠释MODE_PULL_DOWN_TO_REFRESH =为0x1;
    公共静态最终诠释MODE_PULL_UP_TO_REFRESH = 0X2;
    公共静态最终诠释MODE_BOTH = 0x3中;    // ================================================ ===========
    //领域
    // ================================================ ===========    私人INT状态= PULL_TO_REFRESH;
    私人INT模式= MODE_PULL_DOWN_TO_REFRESH;
    私人诠释CURRENTMODE;
    私人布尔disableScrollingWhileRefreshing = TRUE;    私人ŧ适配器视图;
    私人布尔isPullToRefreshEnabled = TRUE;    私人LoadingLayout headerLayout;
    私人LoadingLayout footerLayout;
    私人诠释headerHeight;    私人最终处理程序处理程序=新的处理程序();    私人OnTouchListener onTouchListener;
    私人OnRefreshListener onRefreshListener;
    私人OnScrollListener onScrollListener;    私人OnLastItemVisibleListener onLastItemVisibleListener;
    私人INT lastSavedFirstVisibleItem = -1;    私人SmoothScrollRunnable currentSmoothScrollRunnable;    私人浮动startY = -1;
    私人最终浮动[] = lastYs新的浮动[EVENT_COUNT]    // ================================================ ===========
    //构造函数
    // ================================================ ===========    公共PullToRefreshBase(上下文的背景下){
        这(背景下,NULL);
    }    公共PullToRefreshBase(上下文的背景下,INT模式){
        这(背景);
        this.mode =模式;
    }    公共PullToRefreshBase(上下文的背景下,ATTRS的AttributeSet){
        超(背景下,ATTRS);
        的init(背景下,ATTRS);
    }    // ================================================ ===========
    //吸气和放大器;二传手
    // ================================================ ===========    / **
     *获取包裹适配器视图。这里返回任何已是
     *添加到内容视图。
     *
     返回:这是目前包裹适配器视图
     * /
    公众最终t getAdapterView(){
        返回适配器视图;
    }    / **
     *是否启用上拉来刷新
     *
     * @返回启用
     * /
    公共最后布尔isPullToRefreshEnabled(){
        返回isPullToRefreshEnabled;
    }    公共无效setDisableScrollingWhileRefreshing(
            布尔disableScrollingWhileRefreshing){
        this.disableScrollingWhileRefreshing = disableScrollingWhileRefreshing;
    }    / **
     *标记当前刷新为完成。将重置UI和隐藏
     *全新看法
     * /
    公众最终无效onRefreshComplete(){
        resetHeader();
    }    公众最终无效setOnLastItemVisibleListener(
            OnLastItemVisibleListener监听){
        onLastItemVisibleListener =侦听器;
    }    公众最终无效setOnRefreshListener(OnRefreshListener监听){
        onRefreshListener =侦听器;
    }    / **
     *一个突变启用/禁用拉来刷新当前适配器视图
     *
     * @参数启用
     *是否拉要刷新应使用
     * /
    公众最终无效setPullToRefreshEnabled(布尔启用){
        this.isPullToRefreshEnabled =启用;
    }    公众最终无效setReleaseLabel(字符串releaseLabel){
        如果(NULL!= headerLayout){
            headerLayout.setReleaseLabel(releaseLabel);
        }
        如果(NULL!= footerLayout){
            footerLayout.setReleaseLabel(releaseLabel);
        }
    }    公众最终无效setPullLabel(字符串pullLabel){
        如果(NULL!= headerLayout){
            headerLayout.setPullLabel(pullLabel);
        }
        如果(NULL!= footerLayout){
            footerLayout.setPullLabel(pullLabel);
        }
    }    公众最终无效setRefreshingLabel(字符串refreshingLabel){
        如果(NULL!= headerLayout){
            headerLayout.setRefreshingLabel(refreshingLabel);
        }
        如果(NULL!= footerLayout){
            footerLayout.setRefreshingLabel(refreshingLabel);
        }
    }    // ================================================ ===========
    //方法/从父类/接口
    // ================================================ ===========    公众最终无效setOnScrollListener(OnScrollListener监听){
        onScrollListener =侦听器;
    }    @覆盖
    公众最终无效setOnTouchListener(OnTouchListener监听){
        onTouchListener =侦听器;
    }    公众最终无效onScroll(最终AbsListView来看,
            最终诠释firstVisibleItem,最终诠释visibleItemCount,
            最终诠释totalItemCount){        如果(NULL!= onLastItemVisibleListener){
            //检测是否最后一个项目是可见
            如果(visibleItemCount大于0&放大器;&放大器; visibleItemCount&下; totalItemCount
                    &功放;&安培; (firstVisibleItem + visibleItemCount == totalItemCount)){
                //只处理第一个事件
                如果(firstVisibleItem!= lastSavedFirstVisibleItem){
                    lastSavedFirstVisibleItem = firstVisibleItem;
                    onLastItemVisibleListener.onLastItemVisible();
                }
            }
        }        如果(NULL!= onScrollListener){
            onScrollListener.onScroll(查看,firstVisibleItem,visibleItemCount,
                    totalItemCount);
        }
    }    公众最终无效onScrollStateChanged(最终AbsListView来看,
            最终诠释scrollState){
        如果(NULL!= onScrollListener){
            onScrollListener.onScrollStateChanged(查看,scrollState);
        }
    }    // @覆盖
    公共最后布尔onTouch(查看视图,MotionEvent EV){
        如果(isPullToRefreshEnabled){
            //返回true这里停在ListView是当我们滚动
            //刷新
            如果(状态== REFRESHING&放大器;&安培; disableScrollingWhileRefreshing){
                返回true;
            }否则如果(onAdapterViewTouch(查看,EV)){
                返回true;
            }
        }        如果(NULL!= onTouchListener){
            返回onTouchListener.onTouch(查看,EV);
        }        返回false;
    }    / **
     *这是通过派生类实现返回创建适配器视图。
     *如果你需要使用一个自定义的适配器视图(如自定义的ListView)
     *重写此方法并返回您的自定义类的一个实例。
     *
     *请务必设置视图的ID在这种方法中,特别是如果你
     *使用ListActivity或ListFragment。
     *
     * @参数方面
     * @参数ATTRS
     *从包裹类的AttributeSet。也就是说,任何你
     *包括在XML布局声明将被路由到
     *适配器视图
     返回:该适配器视图的新实例
     * /
    保护性抽象ŧcreateAdapterView(上下文的背景下,ATTRS的AttributeSet);    // ================================================ ===========
    // 方法
    // ================================================ ===========    保护最终无效resetHeader(){
        状态= PULL_TO_REFRESH;
        initializeYsHistory();
        startY = -1;        如果(NULL!= headerLayout){
            headerLayout.reset();
        }
        如果(NULL!= footerLayout){
            footerLayout.reset();
        }        smoothScrollTo(0);
    }    私人无效的init(上下文的背景下,ATTRS的AttributeSet){        setOrientation(LinearLayout.VERTICAL);        从XML // Styleables
        最后一个TypedArray = context.obtainStyledAttributes(ATTRS,
                R.styleable.PullToRefresh);
        模式= a.getInteger(R.styleable.PullToRefresh_mode,
                MODE_PULL_DOWN_TO_REFRESH);        //适配器视图
        //通过传递ATTRS,我们可以通过XML添加的ListView / GridView的PARAMS
        适配器视图= this.createAdapterView(背景下,ATTRS);
        adapterView.setOnTouchListener(本);
        adapterView.setOnScrollListener(本);
        addView(适配器视图,新LinearLayout.LayoutParams(
                LayoutParams.FILL_PARENT,0,1.0F));        //加载视图弦乐
        字符串pullLabel =上下文
                .getString(R.string.pull_to_refresh_pull_label);
        字符串refreshingLabel =上下文
                .getString(R.string.pull_to_refresh_refreshing_label);
        字符串releaseLabel =上下文
                .getString(R.string.pull_to_refresh_release_label);        //添加加载浏览
        如果(==模式|| MODE_PULL_DOWN_TO_REFRESH ==模式MODE_BOTH){
            headerLayout =新LoadingLayout(背景下,
                    MODE_PULL_DOWN_TO_REFRESH,releaseLabel,pullLabel,
                    refreshingLabel);
            addView(headerLayout,0,新LinearLayout.LayoutParams(
                    ViewGroup.LayoutParams.FILL_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT));
            measureView(headerLayout);
            headerHeight = headerLayout.getMeasuredHeight();
        }
        如果(==模式|| MODE_PULL_UP_TO_REFRESH ==模式MODE_BOTH){
            footerLayout =新LoadingLayout(背景下,MODE_PULL_UP_TO_REFRESH,
                    releaseLabel,pullLabel,refreshingLabel);
            addView(footerLayout,新LinearLayout.LayoutParams(
                    ViewGroup.LayoutParams.FILL_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT));
            measureView(footerLayout);
            headerHeight = footerLayout.getMeasuredHeight();
        }        从XML // Styleables
        如果(a.hasVa​​lue(R.styleable.PullToRefresh_headerTextColor)){
            最终诠释颜色= a.getColor(
                    R.styleable.PullToRefresh_headerTextColor,Color.BLACK);
            如果(NULL!= headerLayout){
                headerLayout.setTextColor(颜色);
            }
            如果(NULL!= footerLayout){
                footerLayout.setTextColor(颜色);
            }
        }
        如果(a.hasVa​​lue(R.styleable.PullToRefresh_headerBackground)){
            this.setBackgroundResource(a.getResourceId(
                    R.styleable.PullToRefresh_headerBackground,Color.WHITE));
        }
        如果(a.hasVa​​lue(R.styleable.PullToRefresh_adapterViewBackground)){
            adapterView.setBackgroundResource(a.getResourceId(
                    R.styleable.PullToRefresh_adapterViewBackground,
                    Color.WHITE));
        }
        a.recycle();        //隐藏加载浏览
        开关(模式){
        案例MODE_BOTH:
            setPadding(getPaddingLeft(),-headerHeight,getPaddingRight(),
                    -headerHeight);
            打破;
        案例MODE_PULL_UP_TO_REFRESH:
            setPadding(getPaddingLeft(),getPaddingTop(),getPaddingRight(),
                    -headerHeight);
            打破;
        案例MODE_PULL_DOWN_TO_REFRESH:
        默认:
            setPadding(getPaddingLeft(),-headerHeight,getPaddingRight(),
                    getPaddingBottom());
            打破;
        }        //如果我们不使用MODE_BOTH,那么就设置CURRENTMODE当前
        //模式
        如果(模式!= MODE_BOTH){
            CURRENTMODE =模式;
        }
    }    私人无效measureView(查看孩子){
        ViewGroup.LayoutParams p值= child.getLayoutParams();
        如果(P == NULL){
            P =新ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT);
        }        INT childWidthSpec = ViewGroup.getChildMeasureSpec(0,0 + 0 p.width);
        INT lpHeight = p.height;
        INT childHeightSpec;
        如果(lpHeight大于0){
            childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight,
                    MeasureSpec.EXACTLY);
        }其他{
            childHeightSpec = MeasureSpec.makeMeasureSpec(0,
                    MeasureSpec.UNSPECIFIED);
        }
        child.measure(childWidthSpec,childHeightSpec);
    }    私人布尔onAdapterViewTouch(查看视图,MotionEvent事件){        开关(event.getAction()){
        案例MotionEvent.ACTION_MOVE:
            updateEventStates(事件);            如果(isPullingToRefresh()及&放大器; startY == -1){
                startY = event.getY();                //需要设置当前的模式,如果我们同时使用
                如果(==模式MODE_BOTH){
                    如果(isUserDraggingDownwards()){
                        CURRENTMODE = MODE_PULL_DOWN_TO_REFRESH;
                    }否则如果(isUserDraggingUpwards()){
                        CURRENTMODE = MODE_PULL_UP_TO_REFRESH;
                    }
                }
                返回false;
            }            如果(startY = -1&放大器;!&放大器;!adapterView.is pressed()){
                pullEvent(事件,startY);
                返回true;
            }
            打破;
        案例MotionEvent.ACTION_UP:
            initializeYsHistory();
            startY = -1;            如果(状态== RELEASE_TO_REFRESH){
                setRefreshing();
                如果(onRefreshListener!= NULL){
                    onRefreshListener.onRefresh();
                }
            }其他{
                smoothScrollTo(0);
            }
            打破;
        }        返回false;
    }    私人无效pullEvent(MotionEvent事件,浮firstY){
        浮averageY =平均(lastYs);        最终诠释高度;
        开关(CURRENTMODE){
        案例MODE_PULL_UP_TO_REFRESH:
            高度=(int)的Math.max(firstY - averageY,0);
            setHeaderScroll(高度);
            打破;
        案例MODE_PULL_DOWN_TO_REFRESH:
        默认:
            高度=(int)的Math.max(averageY - firstY,0);
            setHeaderScroll(-height);
            打破;
        }        如果(状态== PULL_TO_REFRESH&放大器;&安培; headerHeight<高度){
            状态= RELEASE_TO_REFRESH;
            如果(NULL!= headerLayout){
                headerLayout.releaseToRefresh();
            }
            如果(NULL!= footerLayout){
                footerLayout.releaseToRefresh();
            }
        }否则如果(状态== RELEASE_TO_REFRESH&放大器;&安培; headerHeight> =身高){
            状态= PULL_TO_REFRESH;
            如果(NULL!= headerLayout){
                headerLayout.pullToRefresh();
            }
            如果(NULL!= footerLayout){
                footerLayout.pullToRefresh();
            }
        }
    }    私人无效setHeaderScroll(int y)对{
        scrollTo(0,y)基
    }    私人无效setRefreshing(){
        状态=爽口;
        如果(NULL!= headerLayout){
            headerLayout.refreshing();
        }
        如果(NULL!= footerLayout){
            footerLayout.refreshing();
        }        开关(CURRENTMODE){
        案例MODE_PULL_DOWN_TO_REFRESH:
            smoothScrollTo(-headerHeight);
            打破;
        案例MODE_PULL_UP_TO_REFRESH:
            smoothScrollTo(headerHeight);
            打破;
        }
    }    私人浮动平均(浮动[] ysArray){
        浮动平均= 0;
        的for(int i = 0; I< EVENT_COUNT;我++){
            平均+ = ysArray [I]
        }
        返回平均/ EVENT_COUNT;
    }    私人无效initializeYsHistory(){
        的for(int i = 0; I< EVENT_COUNT;我++){
            lastYs [I] = 0;
        }
    }    私人无效updateEventStates(MotionEvent事件){
        的for(int i = 0,Z = event.getHistorySize(); I< Z;我++){
            this.updateEventStates(event.getHistoricalY(I));
        }        this.updateEventStates(event.getY());
    }    私人无效updateEventStates(浮点Y){
        的for(int i = 0; I< EVENT_COUNT - 1;我++){
            lastYs [I] = lastYs第[i + 1];
        }        lastYs [EVENT_COUNT - 1] = Y;
    }    私人布尔isPullingToRefresh(){
        如果(isPullToRefreshEnabled&安培;&安培;!=状态REFRESHING){
            开关(模式){
            案例MODE_PULL_DOWN_TO_REFRESH:
                返回isFirstItemVisible()及&放大器; isUserDraggingDownwards();
            案例MODE_PULL_UP_TO_REFRESH:
                返回isLastItemVisible()及&放大器; isUserDraggingUpwards();
            案例MODE_BOTH:
                返回(isFirstItemVisible()及&放大器; isUserDraggingDownwards())
                        || (isLastItemVisible()及&放大器; isUserDraggingUpwards());
            }
        }
        返回false;
    }    私人布尔isFirstItemVisible(){
        如果(this.adapterView.getCount()== 0){
            返回true;
        }否则如果(adapterView.getFirstVisiblePosition()== 0){
            返回adapterView.getChildAt(0).getTop()&GT = adapterView.getTop();
        }其他{
            返回false;
        }
    }    私人布尔isLastItemVisible(){
        最终诠释计数= this.adapterView.getCount();
        如果(计数== 0){
            返回true;
        }否则如果(adapterView.getLastVisiblePosition()==计数 - 1){
            返回true;
        }其他{
            返回false;
        }
    }    私人布尔isUserDraggingDownwards(){
        返回this.isUserDraggingDownwards(0,EVENT_COUNT - 1);
    }    私人布尔isUserDraggingDownwards(从,INT到INT){
        返回lastYs [从] = 0&安培;!&安培; lastYs [来]!= 0
                &功放;&安培; Math.abs(lastYs [从] - lastYs [转])GT; 10
                &功放;&安培; [从]&LT lastYs; lastYs [来]
    }    私人布尔isUserDraggingUpwards(){
        返回this.isUserDraggingUpwards(0,EVENT_COUNT - 1);
    }    私人布尔isUserDraggingUpwards(从,INT到INT){
        返回lastYs [从] = 0&安培;!&安培; lastYs [来]!= 0
                &功放;&安培; Math.abs(lastYs [来] - [从] lastYs)GT; 10
                &功放;&安培; lastYs [以< lastYs [从]
    }    私人无效smoothScrollTo(int y)对{
        如果(NULL!= currentSmoothScrollRunnable){
            currentSmoothScrollRunnable.stop();
        }        this.currentSmoothScrollRunnable =新SmoothScrollRunnable(处理器,
                getScrollY(),y)基
        handler.post(currentSmoothScrollRunnable);
    }    // ================================================ ===========
    //内部和匿名类
    // ================================================ ===========    公共静态界面OnRefreshListener {        公共无效onRefresh();    }    公共静态界面OnLastItemVisibleListener {        公共无效onLastItemVisible();    }}

希望这将有助于你从你的问题了。让我知道如果你还在寻找任何困难。

I am using the feature pull down to refresh by using this library of chrisbanes But when I tried to import this widget in my xml file It shows me the following error.Please help me how to solve this. Error:

com.handmark.pulltorefresh.library.PullToRefreshListView failed to instantiate.

解决方案

I would definitely take a look at Chris Banes' implementation of pull-to-refresh. His code does not only include this interaction style for ListView, but also GridView and WebView.

Especially the latter will be of interest in your case, since it's an example implementation of pull-to-refresh for a view that does not use an adapter for its content. If you look at the source code, you'll see that every concrete pull-to-refreh view in Banes' project extends from a generic PullToRefreshBase, which contains most of the logic for animation and refreshing. The benefit of having that base class is that doing the same thing for any other type of view, e.g. a TextView, should be pretty straightforward.

The only drawback of this approach is that the implementation is a wrapper for other views, meaning you'll have write a couple of extra lines to get the actual view. So it's not a full drop-in replacement. However, its functionality and features far exceed that little inconvenience.

EDITED :

Look at the Below Code i have implemented

in your Main JAVA File :

PullToRefreshListView listview;

listview = (PullToRefreshListView) findViewById(R.id.airpost_listView);

    listview.setOnRefreshListener(new OnRefreshListener() {
        public void onRefresh() {
            // TODO Auto-generated method stub
            new GetPost().execute(); // AsyncTask where you can put your  logic when to call the listview for getting new data or let it be same as before
        }
    });

Listview Defined in xml File:

 <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="@drawable/bhavesh"
        android:padding="5dp" >

        <com.FlightMate.AirpostTab.PullToRefreshListView
            android:id="@+id/airpost_listView"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:background="#ffffff"
            android:cacheColorHint="@android:color/transparent"
            android:divider="#00000000" />
    </LinearLayout>

Here is PullToRefreshListView :

    package com.FlightMate.AirpostTab;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.ListView;

public class PullToRefreshListView extends PullToRefreshBase<ListView> {

    public PullToRefreshListView(Context context) {
        super(context);
    }

    public PullToRefreshListView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected final ListView createAdapterView(Context context,
            AttributeSet attrs) {
        ListView lv = new ListView(context, attrs);
        // Set it to this so it can be used in ListActivity/ListFragment

        lv.setId(android.R.id.list);
        return lv;
    }

}

here is PullToRefreshBase :

    package com.FlightMate.AirpostTab;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.Interpolator;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.LinearLayout;

import com.FlightMate.R;

public abstract class PullToRefreshBase<T extends AbsListView> extends
        LinearLayout implements OnTouchListener, OnScrollListener {

    private final class SmoothScrollRunnable implements Runnable {

        static final int ANIMATION_DURATION_MS = 190;
        static final int ANIMATION_FPS = 1000 / 60;

        private final Interpolator interpolator;
        private final int scrollToY;
        private final int scrollFromY;
        private final Handler handler;

        private boolean continueRunning = true;
        private long startTime = -1;
        private int currentY = -1;

        public SmoothScrollRunnable(Handler handler, int fromY, int toY) {
            this.handler = handler;
            this.scrollFromY = fromY;
            this.scrollToY = toY;
            this.interpolator = new AccelerateDecelerateInterpolator();
        }

        // @Override
        public void run() {

            /**
             * Only set startTime if this is the first time we're starting, else
             * actually calculate the Y delta
             */
            if (startTime == -1) {
                startTime = System.currentTimeMillis();
            } else {

                /**
                 * We do do all calculations in long to reduce software float
                 * calculations. We use 1000 as it gives us good accuracy and
                 * small rounding errors
                 */
                long normalizedTime = (1000 * (System.currentTimeMillis() - startTime))
                        / ANIMATION_DURATION_MS;
                normalizedTime = Math.max(Math.min(normalizedTime, 1000), 0);

                final int deltaY = Math
                        .round((scrollFromY - scrollToY)
                                * interpolator
                                        .getInterpolation(normalizedTime / 1000f));
                this.currentY = scrollFromY - deltaY;
                setHeaderScroll(currentY);
            }

            // If we're not at the target Y, keep going...
            if (continueRunning && scrollToY != currentY) {
                handler.postDelayed(this, ANIMATION_FPS);
            }
        }

        public void stop() {
            this.continueRunning = false;
            this.handler.removeCallbacks(this);
        }
    };

    // ===========================================================
    // Constants
    // ===========================================================

    static final int PULL_TO_REFRESH = 0;
    static final int RELEASE_TO_REFRESH = PULL_TO_REFRESH + 1;
    static final int REFRESHING = RELEASE_TO_REFRESH + 1;
    static final int EVENT_COUNT = 3;

    public static final int MODE_PULL_DOWN_TO_REFRESH = 0x1;
    public static final int MODE_PULL_UP_TO_REFRESH = 0x2;
    public static final int MODE_BOTH = 0x3;

    // ===========================================================
    // Fields
    // ===========================================================

    private int state = PULL_TO_REFRESH;
    private int mode = MODE_PULL_DOWN_TO_REFRESH;
    private int currentMode;
    private boolean disableScrollingWhileRefreshing = true;

    private T adapterView;
    private boolean isPullToRefreshEnabled = true;

    private LoadingLayout headerLayout;
    private LoadingLayout footerLayout;
    private int headerHeight;

    private final Handler handler = new Handler();

    private OnTouchListener onTouchListener;
    private OnRefreshListener onRefreshListener;
    private OnScrollListener onScrollListener;

    private OnLastItemVisibleListener onLastItemVisibleListener;
    private int lastSavedFirstVisibleItem = -1;

    private SmoothScrollRunnable currentSmoothScrollRunnable;

    private float startY = -1;
    private final float[] lastYs = new float[EVENT_COUNT];

    // ===========================================================
    // Constructors
    // ===========================================================

    public PullToRefreshBase(Context context) {
        this(context, null);
    }

    public PullToRefreshBase(Context context, int mode) {
        this(context);
        this.mode = mode;
    }

    public PullToRefreshBase(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    // ===========================================================
    // Getter & Setter
    // ===========================================================

    /**
     * Get the Wrapped AdapterView. Anything returned here has already been
     * added to the content view.
     * 
     * @return The AdapterView which is currently wrapped
     */
    public final T getAdapterView() {
        return adapterView;
    }

    /**
     * Whether Pull-to-Refresh is enabled
     * 
     * @return enabled
     */
    public final boolean isPullToRefreshEnabled() {
        return isPullToRefreshEnabled;
    }

    public void setDisableScrollingWhileRefreshing(
            boolean disableScrollingWhileRefreshing) {
        this.disableScrollingWhileRefreshing = disableScrollingWhileRefreshing;
    }

    /**
     * Mark the current Refresh as complete. Will Reset the UI and hide the
     * Refreshing View
     */
    public final void onRefreshComplete() {
        resetHeader();
    }

    public final void setOnLastItemVisibleListener(
            OnLastItemVisibleListener listener) {
        onLastItemVisibleListener = listener;
    }

    public final void setOnRefreshListener(OnRefreshListener listener) {
        onRefreshListener = listener;
    }

    /**
     * A mutator to enable/disable Pull-to-Refresh for the current AdapterView
     * 
     * @param enable
     *            Whether Pull-To-Refresh should be used
     */
    public final void setPullToRefreshEnabled(boolean enabled) {
        this.isPullToRefreshEnabled = enabled;
    }

    public final void setReleaseLabel(String releaseLabel) {
        if (null != headerLayout) {
            headerLayout.setReleaseLabel(releaseLabel);
        }
        if (null != footerLayout) {
            footerLayout.setReleaseLabel(releaseLabel);
        }
    }

    public final void setPullLabel(String pullLabel) {
        if (null != headerLayout) {
            headerLayout.setPullLabel(pullLabel);
        }
        if (null != footerLayout) {
            footerLayout.setPullLabel(pullLabel);
        }
    }

    public final void setRefreshingLabel(String refreshingLabel) {
        if (null != headerLayout) {
            headerLayout.setRefreshingLabel(refreshingLabel);
        }
        if (null != footerLayout) {
            footerLayout.setRefreshingLabel(refreshingLabel);
        }
    }

    // ===========================================================
    // Methods for/from SuperClass/Interfaces
    // ===========================================================

    public final void setOnScrollListener(OnScrollListener listener) {
        onScrollListener = listener;
    }

    @Override
    public final void setOnTouchListener(OnTouchListener listener) {
        onTouchListener = listener;
    }

    public final void onScroll(final AbsListView view,
            final int firstVisibleItem, final int visibleItemCount,
            final int totalItemCount) {

        if (null != onLastItemVisibleListener) {
            // detect if last item is visible
            if (visibleItemCount > 0 && visibleItemCount < totalItemCount
                    && (firstVisibleItem + visibleItemCount == totalItemCount)) {
                // only process first event
                if (firstVisibleItem != lastSavedFirstVisibleItem) {
                    lastSavedFirstVisibleItem = firstVisibleItem;
                    onLastItemVisibleListener.onLastItemVisible();
                }
            }
        }

        if (null != onScrollListener) {
            onScrollListener.onScroll(view, firstVisibleItem, visibleItemCount,
                    totalItemCount);
        }
    }

    public final void onScrollStateChanged(final AbsListView view,
            final int scrollState) {
        if (null != onScrollListener) {
            onScrollListener.onScrollStateChanged(view, scrollState);
        }
    }

    // @Override
    public final boolean onTouch(View view, MotionEvent ev) {
        if (isPullToRefreshEnabled) {
            // Returning true here stops the ListView being scrollable while we
            // refresh
            if (state == REFRESHING && disableScrollingWhileRefreshing) {
                return true;
            } else if (onAdapterViewTouch(view, ev)) {
                return true;
            }
        }

        if (null != onTouchListener) {
            return onTouchListener.onTouch(view, ev);
        }

        return false;
    }

    /**
     * This is implemented by derived classes to return the created AdapterView.
     * If you need to use a custom AdapterView (such as a custom ListView),
     * override this method and return an instance of your custom class.
     * 
     * Be sure to set the ID of the view in this method, especially if you're
     * using a ListActivity or ListFragment.
     * 
     * @param context
     * @param attrs
     *            AttributeSet from wrapped class. Means that anything you
     *            include in the XML layout declaration will be routed to the
     *            AdapterView
     * @return New instance of the AdapterView
     */
    protected abstract T createAdapterView(Context context, AttributeSet attrs);

    // ===========================================================
    // Methods
    // ===========================================================

    protected final void resetHeader() {
        state = PULL_TO_REFRESH;
        initializeYsHistory();
        startY = -1;

        if (null != headerLayout) {
            headerLayout.reset();
        }
        if (null != footerLayout) {
            footerLayout.reset();
        }

        smoothScrollTo(0);
    }

    private void init(Context context, AttributeSet attrs) {

        setOrientation(LinearLayout.VERTICAL);

        // Styleables from XML
        final TypedArray a = context.obtainStyledAttributes(attrs,
                R.styleable.PullToRefresh);
        mode = a.getInteger(R.styleable.PullToRefresh_mode,
                MODE_PULL_DOWN_TO_REFRESH);

        // AdapterView
        // By passing the attrs, we can add ListView/GridView params via XML
        adapterView = this.createAdapterView(context, attrs);
        adapterView.setOnTouchListener(this);
        adapterView.setOnScrollListener(this);
        addView(adapterView, new LinearLayout.LayoutParams(
                LayoutParams.FILL_PARENT, 0, 1.0f));

        // Loading View Strings
        String pullLabel = context
                .getString(R.string.pull_to_refresh_pull_label);
        String refreshingLabel = context
                .getString(R.string.pull_to_refresh_refreshing_label);
        String releaseLabel = context
                .getString(R.string.pull_to_refresh_release_label);

        // Add Loading Views
        if (mode == MODE_PULL_DOWN_TO_REFRESH || mode == MODE_BOTH) {
            headerLayout = new LoadingLayout(context,
                    MODE_PULL_DOWN_TO_REFRESH, releaseLabel, pullLabel,
                    refreshingLabel);
            addView(headerLayout, 0, new LinearLayout.LayoutParams(
                    ViewGroup.LayoutParams.FILL_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT));
            measureView(headerLayout);
            headerHeight = headerLayout.getMeasuredHeight();
        }
        if (mode == MODE_PULL_UP_TO_REFRESH || mode == MODE_BOTH) {
            footerLayout = new LoadingLayout(context, MODE_PULL_UP_TO_REFRESH,
                    releaseLabel, pullLabel, refreshingLabel);
            addView(footerLayout, new LinearLayout.LayoutParams(
                    ViewGroup.LayoutParams.FILL_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT));
            measureView(footerLayout);
            headerHeight = footerLayout.getMeasuredHeight();
        }

        // Styleables from XML
        if (a.hasValue(R.styleable.PullToRefresh_headerTextColor)) {
            final int color = a.getColor(
                    R.styleable.PullToRefresh_headerTextColor, Color.BLACK);
            if (null != headerLayout) {
                headerLayout.setTextColor(color);
            }
            if (null != footerLayout) {
                footerLayout.setTextColor(color);
            }
        }
        if (a.hasValue(R.styleable.PullToRefresh_headerBackground)) {
            this.setBackgroundResource(a.getResourceId(
                    R.styleable.PullToRefresh_headerBackground, Color.WHITE));
        }
        if (a.hasValue(R.styleable.PullToRefresh_adapterViewBackground)) {
            adapterView.setBackgroundResource(a.getResourceId(
                    R.styleable.PullToRefresh_adapterViewBackground,
                    Color.WHITE));
        }
        a.recycle();

        // Hide Loading Views
        switch (mode) {
        case MODE_BOTH:
            setPadding(getPaddingLeft(), -headerHeight, getPaddingRight(),
                    -headerHeight);
            break;
        case MODE_PULL_UP_TO_REFRESH:
            setPadding(getPaddingLeft(), getPaddingTop(), getPaddingRight(),
                    -headerHeight);
            break;
        case MODE_PULL_DOWN_TO_REFRESH:
        default:
            setPadding(getPaddingLeft(), -headerHeight, getPaddingRight(),
                    getPaddingBottom());
            break;
        }

        // If we're not using MODE_BOTH, then just set currentMode to current
        // mode
        if (mode != MODE_BOTH) {
            currentMode = mode;
        }
    }

    private void measureView(View child) {
        ViewGroup.LayoutParams p = child.getLayoutParams();
        if (p == null) {
            p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT);
        }

        int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0 + 0, p.width);
        int lpHeight = p.height;
        int childHeightSpec;
        if (lpHeight > 0) {
            childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight,
                    MeasureSpec.EXACTLY);
        } else {
            childHeightSpec = MeasureSpec.makeMeasureSpec(0,
                    MeasureSpec.UNSPECIFIED);
        }
        child.measure(childWidthSpec, childHeightSpec);
    }

    private boolean onAdapterViewTouch(View view, MotionEvent event) {

        switch (event.getAction()) {
        case MotionEvent.ACTION_MOVE:
            updateEventStates(event);

            if (isPullingToRefresh() && startY == -1) {
                startY = event.getY();

                // Need to set current Mode if we're using both
                if (mode == MODE_BOTH) {
                    if (isUserDraggingDownwards()) {
                        currentMode = MODE_PULL_DOWN_TO_REFRESH;
                    } else if (isUserDraggingUpwards()) {
                        currentMode = MODE_PULL_UP_TO_REFRESH;
                    }
                }
                return false;
            }

            if (startY != -1 && !adapterView.isPressed()) {
                pullEvent(event, startY);
                return true;
            }
            break;
        case MotionEvent.ACTION_UP:
            initializeYsHistory();
            startY = -1;

            if (state == RELEASE_TO_REFRESH) {
                setRefreshing();
                if (onRefreshListener != null) {
                    onRefreshListener.onRefresh();
                }
            } else {
                smoothScrollTo(0);
            }
            break;
        }

        return false;
    }

    private void pullEvent(MotionEvent event, float firstY) {
        float averageY = average(lastYs);

        final int height;
        switch (currentMode) {
        case MODE_PULL_UP_TO_REFRESH:
            height = (int) Math.max(firstY - averageY, 0);
            setHeaderScroll(height);
            break;
        case MODE_PULL_DOWN_TO_REFRESH:
        default:
            height = (int) Math.max(averageY - firstY, 0);
            setHeaderScroll(-height);
            break;
        }

        if (state == PULL_TO_REFRESH && headerHeight < height) {
            state = RELEASE_TO_REFRESH;
            if (null != headerLayout) {
                headerLayout.releaseToRefresh();
            }
            if (null != footerLayout) {
                footerLayout.releaseToRefresh();
            }
        } else if (state == RELEASE_TO_REFRESH && headerHeight >= height) {
            state = PULL_TO_REFRESH;
            if (null != headerLayout) {
                headerLayout.pullToRefresh();
            }
            if (null != footerLayout) {
                footerLayout.pullToRefresh();
            }
        }
    }

    private void setHeaderScroll(int y) {
        scrollTo(0, y);
    }

    private void setRefreshing() {
        state = REFRESHING;
        if (null != headerLayout) {
            headerLayout.refreshing();
        }
        if (null != footerLayout) {
            footerLayout.refreshing();
        }

        switch (currentMode) {
        case MODE_PULL_DOWN_TO_REFRESH:
            smoothScrollTo(-headerHeight);
            break;
        case MODE_PULL_UP_TO_REFRESH:
            smoothScrollTo(headerHeight);
            break;
        }
    }

    private float average(float[] ysArray) {
        float avg = 0;
        for (int i = 0; i < EVENT_COUNT; i++) {
            avg += ysArray[i];
        }
        return avg / EVENT_COUNT;
    }

    private void initializeYsHistory() {
        for (int i = 0; i < EVENT_COUNT; i++) {
            lastYs[i] = 0;
        }
    }

    private void updateEventStates(MotionEvent event) {
        for (int i = 0, z = event.getHistorySize(); i < z; i++) {
            this.updateEventStates(event.getHistoricalY(i));
        }

        this.updateEventStates(event.getY());
    }

    private void updateEventStates(float y) {
        for (int i = 0; i < EVENT_COUNT - 1; i++) {
            lastYs[i] = lastYs[i + 1];
        }

        lastYs[EVENT_COUNT - 1] = y;
    }

    private boolean isPullingToRefresh() {
        if (isPullToRefreshEnabled && state != REFRESHING) {
            switch (mode) {
            case MODE_PULL_DOWN_TO_REFRESH:
                return isFirstItemVisible() && isUserDraggingDownwards();
            case MODE_PULL_UP_TO_REFRESH:
                return isLastItemVisible() && isUserDraggingUpwards();
            case MODE_BOTH:
                return (isFirstItemVisible() && isUserDraggingDownwards())
                        || (isLastItemVisible() && isUserDraggingUpwards());
            }
        }
        return false;
    }

    private boolean isFirstItemVisible() {
        if (this.adapterView.getCount() == 0) {
            return true;
        } else if (adapterView.getFirstVisiblePosition() == 0) {
            return adapterView.getChildAt(0).getTop() >= adapterView.getTop();
        } else {
            return false;
        }
    }

    private boolean isLastItemVisible() {
        final int count = this.adapterView.getCount();
        if (count == 0) {
            return true;
        } else if (adapterView.getLastVisiblePosition() == count - 1) {
            return true;
        } else {
            return false;
        }
    }

    private boolean isUserDraggingDownwards() {
        return this.isUserDraggingDownwards(0, EVENT_COUNT - 1);
    }

    private boolean isUserDraggingDownwards(int from, int to) {
        return lastYs[from] != 0 && lastYs[to] != 0
                && Math.abs(lastYs[from] - lastYs[to]) > 10
                && lastYs[from] < lastYs[to];
    }

    private boolean isUserDraggingUpwards() {
        return this.isUserDraggingUpwards(0, EVENT_COUNT - 1);
    }

    private boolean isUserDraggingUpwards(int from, int to) {
        return lastYs[from] != 0 && lastYs[to] != 0
                && Math.abs(lastYs[to] - lastYs[from]) > 10
                && lastYs[to] < lastYs[from];
    }

    private void smoothScrollTo(int y) {
        if (null != currentSmoothScrollRunnable) {
            currentSmoothScrollRunnable.stop();
        }

        this.currentSmoothScrollRunnable = new SmoothScrollRunnable(handler,
                getScrollY(), y);
        handler.post(currentSmoothScrollRunnable);
    }

    // ===========================================================
    // Inner and Anonymous Classes
    // ===========================================================

    public static interface OnRefreshListener {

        public void onRefresh();

    }

    public static interface OnLastItemVisibleListener {

        public void onLastItemVisible();

    }

}

Hope it will Help you out from your Problem. let me know if you are still finding any difficulties.

这篇关于在下拉错误刷新列表视图的android的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆