开发者

how to do pulltorefresh listview by Johan Nilson inversely to do a pull UP to refresh?

I have used the pulltorefresh example of Johan Nilson.Its working excellent.But I need to apply inversely also.i.e pull Up to refresh.I applied all methods inversely but I couldnt get the solution.Pls give some ideas.I have posted my code also.

public class PullToRefreshListView extends ListView implements OnScrollListener {

    private static final int TAP_TO_REFRESH = 1;
    private static final int PULL_TO_REFRESH = 2;
    private static final int RELEASE_TO_REFRESH = 3;
    private static final int REFRESHING = 4;

    private OnRefreshListener mOnRefreshListener;
    private OnScrollListener mOnScrollListener;
    private LayoutInflater mInflater;
    private RelativeLayout mRefreshView;
    private TextView mRefreshViewText;
    private ImageView mRefreshViewImage;
    private int mCurrentScrollState;
    private int mRefreshState;
    private RotateAnimation mFlipAnimation;
    private RotateAnimation mReverseFlipAnimation;
    private int mRefreshViewHeight;
    private int mRefreshOriginalTopPadding;
    private int mRefreshOriginalBottomPadding;
    private int mLastMotionY;

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

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

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

    private void init(Context context) {
        // Load all of the animations we need in code rather than through XML
        mFlipAnimation = new RotateAnimation(0, -180,
                RotateAnimation.RELATIVE_TO_SELF, 0.5f,
                RotateAnimation.RELATIVE_TO_SELF, 0.5f);
        mFlipAnimation.setInterpolator(new LinearInterpolator());
        mFlipAnimation.setDuration(250);
        mFlipAnimation.setFillAfter(true);
        mReverseFlipAnimation = new RotateAnimation(-180, 0,
                RotateAnimation.RELATIVE_TO_SELF, 0.5f,
                RotateAnimation.RELATIVE_TO_SELF, 0.5f);
        mReverseFlipAnimation.setInterpolator(new LinearInterpolator());
        mReverseFlipAnimation.setDuration(250);
        mReverseFlipAnimation.setFillAfter(true);
        mInflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        mRefreshView = (RelativeLayout) mInflater.inflate(
                R.layout.pulltorefresh, this, false);
        mRefreshViewText = (TextView) mRefreshView
                .findViewById(R.id.pull_to_refresh_text);
        mRefreshViewImage = (ImageView) mRefreshView
                .findViewById(R.id.pull_to_refresh_image);
        mRefreshViewImage.setMinimumHeight(30);
        mRefreshOriginalTopPadding = mRefreshView.getPaddingTop();
        mRefreshOriginalBottomPadding = mRefreshView.getPaddingBottom();
        mRefreshState = TAP_TO_REFRESH;
        addHeaderView(mRefreshView);
        addFooterView(mRefreshView);
        super.setOnScrollListener(this);
        mRefreshViewHeight = mRefreshView.getMeasuredHeight();
    }

    @Override
    protected void onAttachedToWindow() {
        setSelection(1);

    }

    @Override
    public void setAdapter(ListAdapter adapter) {
        super.setAdapter(adapter);

        setSelection(1);

    }

    @Override
    public void setOnScrollListener(AbsListView.OnScrollListener l) {
        mOnScrollListener = l;

    }

    public void setOnRefreshListener(OnRefreshListener onRefreshListener) {
        mOnRefreshListener = onRefreshListener;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        final int y = (int) event.getY();

        switch (event.getAction()) {
        case MotionEvent.ACTION_UP:
            if (!isVerticalScrollBarEnabled()) {
                setVerticalScrollBarEnabled(true);
            }
            if (getFirstVisiblePosition() == 0 && mRefreshState != REFRESHING) {
                if ((mRefreshView.getBottom() > mRefreshViewHeight || mRefreshView
                        .getTop() >= 0) && mRefreshState == RELEASE_TO_REFRESH) {
                    // Initiate the refresh

                    onRefresh();

                }

            } else if (mRefreshView.getBottom() < mRefreshViewHeight
                    || mRefreshView.getTop() < 0) {
                // Abort refresh and scroll down below the refresh view
                resetHeader();
                setSelection(1);

            }
            break;
        case MotionEvent.ACTION_DOWN:

            mLastMotionY = y;

        case MotionEvent.ACTION_MOVE:
            applyHeaderPadding(event);
            applyFooterPadding(event);

            break;
        }
        return super.onTouchEvent(event);
    }

    private void applyHeaderPadding(MotionEvent ev) {
        final int historySize = ev.getHistorySize();

        // Workaround for getPointerCount() which is unavailable in 1.5
        // (it's always 1 in 1.5)
        int pointerCount = 1;
        try {
            Method method = MotionEvent.class.getMethod("getPointerCount");
            pointerCount = (Integer) method.invoke(ev);

        } catch (NoSuchMethodException e) {
            pointerCount = 1;

        } catch (IllegalArgumentException e) {
            throw e;
        } catch (IllegalAccessException e) {
            System.err.println("unexpected " + e);
        } catch (InvocationTargetException e) {
            System.err.println("unexpected " + e);
        }

        for (int h = 0; h < historySize; h++) {
            for (int p = 0; p < pointerCount; p++) {
                if (mRefreshState == RELEASE_TO_REFRESH) {
                    if (isVerticalFadingEdgeEnabled()) {
                        setVerticalScrollBarEnabled(false);
                    }

                    int historicalY = 0;

                    try {
                        // For Android > 2.0
                        Method method = MotionEvent.class.getMethod(
                                "getHistoricalY", Integer.TYPE, Integer.TYPE);
                        historicalY = ((Float) method.invoke(ev, p, h))
                                .intValue();

                    } catch (NoSuchMethodException e) {
                        // For Android < 2.0
                        historicalY = (int) (ev.getHistoricalY(h));
                    } catch (IllegalArgumentException e) {
                        throw e;
                    } catch (IllegalAccessException e) {
                        System.err.println("unexpected " + e);
                    } catch (InvocationTargetException e) {
                        System.err.println("unexpected " + e);
                    }

                    // Calculate the padding to apply, we divide by 1.7 to
                    // simulate a more resistant effect during pull.
                    int topPadding = (int) (((historicalY - mLastMotionY) - mRefreshViewHeight) / 1.7);

                    mRefreshView.setPadding(mRefreshView.getPaddingLeft(),
                            topPadding, mRefreshView.getPaddingRight(),
                            mRefreshView.getPaddingBottom());

                }
            }
        }
    }

    private void applyFooterPadding(MotionEvent ev) {
        final int historySize = ev.getHistorySize();

        // Workaround for getPointerCount() which is unavailable in 1.5
        // (it's always 1 in 1.5)
        int pointerCount = 1;
        try {
            Method method = MotionEvent.class.getMethod("getPointerCount");
            pointerCount = (Integer) method.invoke(ev);
            System.out.print(pointerCount);

        } catch (NoSuchMethodException e) {
            pointerCount = 1;
        } catch (IllegalArgumentException e) {
            throw e;
        } catch (IllegalAccessException e) {
            System.err.println("unexpected " + e);
        } catch (InvocationTargetException e) {
            System.err.println("unexpected " + e);
        }

        for (int h = 0; h < historySize; h++) {

            for (int p = 0; p < pointerCount; p++) {
                if (mRefreshState == RELEASE_TO_REFRESH) {
                    if (isVerticalFadingEdgeEnabled()) {

                        setVerticalScrollBarEnabled(false);
                    }

                    int historicalY = 0;
                    try {
                        // For Android > 2.0

                        Method method = MotionEvent.class.getMethod(
                                "getHistoricalY", Integer.TYPE, Integer.TYPE);

                        historicalY = ((Float) method.invoke(ev, p, h))
                                .intValue();
                    } catch (NoSuchMethodException e) {
                        // For Android < 2.0
                        historicalY = (int) (ev.getHistoricalY(h));
                    } catch (IllegalArgumentException e) {
                        throw e;
                    } catch (IllegalAccessException e) {
                        System.err.println("unexpected " + e);
                    } catch (InvocationTargetException e) {
                        System.err.println("unexpected " + e);
                    }


                    // Calculate the padding to apply, we divide by 1.7 to
                    // simulate a more resistant effect during pull.

                    int BottomPadding = (int) (((historicalY - mLastMotionY) - mRefreshViewHeight) / 1.7);

                    mRefreshView.setPadding(mRefreshView.getPaddingLeft(),
                            BottomPadding, mRefreshView.getPaddingRight(),
                            mRefreshView.getPaddingTop());


                }
            }
        }
    }


    private void resetHeaderPadding() {
        mRefreshView.setPadding(mRefreshView.getPaddingLeft(),
                mRefreshOriginalTopPadding, mRefreshView.getPaddingRight(),
                mRefreshView.getPaddingBottom());
    }

    private void resetFooterPadding() {
        mRefreshView.setPadding(mRefreshView.getPaddingLeft(),
                mRefreshOriginalBottomPadding, mRefreshView.getPaddingRight(),
                mRefreshView.getPaddingTop());
    }

    private void resetHeader() {
        if (mRefreshState != TAP_TO_REFRESH) {
            mRefreshState = TAP_TO_REFRESH;

            resetHeaderPadding();
        }
    }

    private void resetFooter() {
        if (mRefreshState != TAP_TO_REFRESH) {
            mRefreshState = TAP_TO_REFRESH;

            resetFooterPadding();
        }
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem,
            int visibleItemCount, int totalItemCount) {
        // When the refresh view is completely visible, change the text to say
        // "Release to refresh..." and flip the arrow drawable.
        if (mCurrentScrollState == SCROLL_STATE_TOUCH_SCROLL
                && mRefreshState != REFRESHING) {
            if (firstVisibleItem == 0) {
                mRefreshViewImage.setVisibility(View.VISIBLE);
                if ((mRefreshView.getBottom() > mRefreshViewHeight + 20 || mRefreshView
                        .getTop() >= 0) && mRefreshState != RELEASE_TO_REFRESH) {
                    mRefreshViewText
                            .setText(R.string.pull_to_refresh_release_label);
                    mRefreshViewImage.clearAnimation();
                    mRefreshViewImage.startAnimation(mFlipAnimation);
                    mRefreshState = RELEASE_TO_REFRESH;
                }

                else if (mRefreshView.getBottom() < mRefreshViewHeight + 20
                        && mRefreshState != PULL_TO_REFRESH) {
                    mRefreshViewText
                            .setText(R.string.pull_to_refresh_pull_label);
                    if (mRefreshState != TAP_TO_REFRESH) {
                        mRefreshViewImage.clearAnimation();
                        mRefreshViewImage.startAnimation(mReverseFlipAnimation);
                    }
                    mRefreshState = PULL_TO_REFRESH;
                }
            } else {

                resetHeader();

            }
        } else if (mCurrentScrollState == SCROLL_STATE_FLING
                && firstVisibleItem == 0 && mRefreshState != REFRESHING) {
            setSelection(1);

        }

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

        }

    }

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        mCurrentScrollState = scrollState;

    }

    public void onRefresh() {
        if (mOnRefreshListener != null) {
            mOnRefreshListener.onRefresh();
        }

    }

    public void onRefreshComplete() {
        resetHeader();
        resetFooter();

        // If refresh view is visible when loading completes, scroll down to
        // the next item.
        if (mRefreshView.getBottom() > 0) {
            invalidateViews();
            setSelection(1);
        }

        if (mRefreshV开发者_StackOverflow中文版iew.getTop() > 0) {
            invalidateViews();
            setSelection(16);
        }
    }

    public interface OnRefreshListener {
        public void onRefresh();

    }
  }


Supports both Pulling Down from the top, and Pulling Up from the bottom (or even both).

Try to use other library Pull-to-Refresh by Chrisbanes

You can pull UP.

It works like a champ

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜