android - Listview 拉动刷新库并添加标题 View

标签 android listview android-listview android-custom-view

我做了拉动来刷新 ListView 为此,我制作了自定义组件 ListView 我在添加标题 View 时遇到问题

或者哪位哥们可以告诉我这是为什么。或者有 friend 在这之前做过

我需要在稍微滚动时在 ListView 中添加搜索栏的标题,如果滚动更多则像拉动刷新一样工作

请检查下面的类

package com.app.refreshableList;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewConfiguration;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.app.XXXXXX.R;
import com.google.android.gms.internal.el;

public class RefreshableListView extends ListView {

Boolean isScrool = false;
private View mHeaderContainer = null;
private View mHeaderView = null;
private ImageView mArrow = null;
private ProgressBar mProgress = null;
private TextView mText = null;
private float mY = 0;
private float mHistoricalY = 0;
private int mHistoricalTop = 0;
private int mInitialHeight = 0;
private boolean mFlag = false;
private boolean mArrowUp = false;
private boolean mIsRefreshing = false;
private int mHeaderHeight = 0;
private OnRefreshListener mListener = null;

private static final int REFRESH = 0;
private static final int NORMAL = 1;
private static final int HEADER_HEIGHT_DP = 62;
private static final String TAG = RefreshableListView.class.getSimpleName();

private ListViewObserver mObserver;
private View mTrackedChild;
private int mTrackedChildPrevPosition;
private int mTrackedChildPrevTop;
OnTouchListener touch;

View vHeader;

@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
    super.onScrollChanged(l, t, oldl, oldt);
    if (mTrackedChild == null) {
        if (getChildCount() > 0) {
            mTrackedChild = getChildInTheMiddle();
            mTrackedChildPrevTop = mTrackedChild.getTop();
            mTrackedChildPrevPosition = getPositionForView(mTrackedChild);
        }
    } else {
        boolean childIsSafeToTrack = mTrackedChild.getParent() == this
                && getPositionForView(mTrackedChild) == mTrackedChildPrevPosition;
        if (childIsSafeToTrack) {
            int top = mTrackedChild.getTop();
            if (mObserver != null) {
                float deltaY = top - mTrackedChildPrevTop;
                mObserver.onScroll(deltaY);

            }
            mTrackedChildPrevTop = top;
        } else {
            mTrackedChild = null;
        }
    }

}

private View getChildInTheMiddle() {
    return getChildAt(getChildCount() / 2);
}

public void setObserver(ListViewObserver observer) {
    mObserver = observer;
}

public RefreshableListView(final Context context) {
    super(context);
    initialize();
}

public RefreshableListView(final Context context, final AttributeSet attrs) {
    super(context, attrs);
    initialize();
}

public RefreshableListView(final Context context, final AttributeSet attrs,
        final int defStyle) {
    super(context, attrs, defStyle);
    initialize();
}

public void setOnRefreshListener(final OnRefreshListener l) {
    mListener = l;
}

@Override
public void setOnTouchListener(OnTouchListener l) {
    // TODO Auto-generated method stub
    super.setOnTouchListener(l);
}

public void completeRefreshing() {
    mProgress.setVisibility(View.INVISIBLE);
    mArrow.setVisibility(View.VISIBLE);
    mHandler.sendMessage(mHandler.obtainMessage(NORMAL, mHeaderHeight, 0));
    mIsRefreshing = false;
    invalidateViews();
}

@Override
public boolean onInterceptTouchEvent(final MotionEvent ev) {
    switch (ev.getAction()) {
    case MotionEvent.ACTION_DOWN:
        mHandler.removeMessages(REFRESH);
        mHandler.removeMessages(NORMAL);
        mY = mHistoricalY = ev.getY();
        if (mHeaderContainer.getLayoutParams() != null) {
            mInitialHeight = mHeaderContainer.getLayoutParams().height;
        }
        // if (isScrool == true) {
        //
        // } else {
        // isScrool = true;
        // addHeaderView(vHeader);
        // // setSelectionAfterHeaderView();
        // // Animation anim =
        // // AnimationUtils.loadAnimation(
        // // getContext(), R.anim.bounce_animation);
        // // startAnimation(anim);
        // // setSelectionAfterHeaderView();
        // // setOverScrollMode(View.OVER_SCROLL_NEVER);
        // // setSelectionFromTop(0, 0);
        // // smoothScrollToPosition(getChildAt(0).getTop()
        // // - vHeader.getHeight());
        // // bottom_layout.setVisibility(View.VISIBLE);
        // }
        break;
    }
    return super.onInterceptTouchEvent(ev);
}

@Override
public boolean onTouchEvent(final MotionEvent ev) {
    switch (ev.getAction()) {
    case MotionEvent.ACTION_MOVE:
        mHistoricalTop = getChildAt(0).getTop();
        break;
    case MotionEvent.ACTION_UP:
        if (!mIsRefreshing) {
            if (mArrowUp) {
                startRefreshing();
                mHandler.sendMessage(mHandler.obtainMessage(REFRESH,
                        (int) (ev.getY() - mY) / 2 + mInitialHeight, 0));
            } else {
                if (getChildAt(0).getTop() == 0) {
                    mHandler.sendMessage(mHandler.obtainMessage(NORMAL,
                            (int) (ev.getY() - mY) / 2 + mInitialHeight, 0));
                }
            }
        } else {
            mHandler.sendMessage(mHandler.obtainMessage(REFRESH,
                    (int) (ev.getY() - mY) / 2 + mInitialHeight, 0));
        }
        mFlag = false;
        break;

    }
    return super.onTouchEvent(ev);
}

@Override
protected boolean overScrollBy(int deltaX, int deltaY, int scrollX,
        int scrollY, int scrollRangeX, int scrollRangeY,
        int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
    // TODO Auto-generated method stub

    Log.e("overscrolled", deltaX + "//" + deltaY + "//" + scrollX + "//"
            + scrollY + "//");

    return super.overScrollBy(deltaX, deltaY, scrollX, scrollY,
            scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY,
            isTouchEvent);
}

@Override
public boolean dispatchTouchEvent(final MotionEvent ev) {
    if (ev.getAction() == MotionEvent.ACTION_MOVE
            && getFirstVisiblePosition() == 0) {
        float direction = ev.getY() - mHistoricalY;
        int height = (int) (ev.getY() - mY) / 2 + mInitialHeight;
        if (height < 0) {
            height = 0;
        }

        float deltaY = Math.abs(mY - ev.getY());
        ViewConfiguration config = ViewConfiguration.get(getContext());
        if (deltaY > config.getScaledTouchSlop()) {

            // Scrolling downward
            if (direction > 0) {
                // Refresh bar is extended if top pixel of the first item is
                // visible
                if (getChildAt(0) != null) {
                    if (getChildAt(0).getTop() == 0) {
                        if (mHistoricalTop < 0) {

                            // mY = ev.getY(); // TODO works without
                            // this?mHistoricalTop = 0;
                        }
                        if (isScrool == true) {

                        } else {
                            isScrool = true;
                            addHeaderView(vHeader);

                            Handler hn = new Handler();

                            hn.postDelayed(new Runnable() {

                                @Override
                                public void run() {
                                    // TODO Auto-generated method stub
                                    smoothScrollByOffset(1);

                                }
                            }, 50);
                        }
                        // Animation anim =
                        // AnimationUtils.loadAnimation(
                        // getContext(), R.anim.bounce_animation);
                        // startAnimation(anim);
                        // setSelectionAfterHeaderView();
                        // setOverScrollMode(View.OVER_SCROLL_NEVER);
                        // setSelectionFromTop(0, 0);
                        // smoothScrollToPosition(getChildAt(0).getTop()
                        // - vHeader.getHeight());
                        // bottom_layout.setVisibility(View.VISIBLE);
                        // }
                        // Extends refresh bar

                        /*****
                         * commented by me on 10-09-2014
                         */
                        Log.e("selected index ",
                                String.valueOf(getScrollY()) + "//"
                                        + getMaxScrollAmount() + "//"
                                        + getAdapter().getCount());
                        setHeaderHeight(height);

                        // Stop list scroll to prevent the list from
                        // overscrolling
                        ev.setAction(MotionEvent.ACTION_CANCEL);
                        mFlag = false;
                    }
                }

            } else if (direction < 0) {
                // Scrolling upward

                // Refresh bar is shortened if top pixel of the first item
                // is
                // visible
                if (getChildAt(0) != null) {
                    if (getChildAt(0).getTop() == 0) {
                        setHeaderHeight(height);

                        // If scroll reaches top of the list, list scroll is
                        // enabled
                        if (getChildAt(1) != null
                                && getChildAt(1).getTop() <= 1 && !mFlag) {
                            ev.setAction(MotionEvent.ACTION_DOWN);
                            mFlag = true;
                        }
                    }
                }
            }
        }

        mHistoricalY = ev.getY();
    }
    try {
        return super.dispatchTouchEvent(ev);
    } catch (Exception e) {
        return false;
    }
}

@Override
public boolean performItemClick(final View view, final int position,
        final long id) {
    if (position == 0) {
        // This is the refresh header element
        return true;
    } else {
        return super.performItemClick(view, position - 1, id);
    }
}

private void initialize() {

    LayoutInflater inflator = (LayoutInflater) getContext()
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    vHeader = inflator.inflate(R.layout.search_header, null);
    LayoutInflater inflater = (LayoutInflater) getContext()
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    mHeaderContainer = inflater.inflate(R.layout.refreshable_list_header,
            null);
    mHeaderView = mHeaderContainer
            .findViewById(R.id.refreshable_list_header);
    mArrow = (ImageView) mHeaderContainer
            .findViewById(R.id.refreshable_list_arrow);
    mProgress = (ProgressBar) mHeaderContainer
            .findViewById(R.id.refreshable_list_progress);
    mText = (TextView) mHeaderContainer
            .findViewById(R.id.refreshable_list_text);
    addHeaderView(mHeaderContainer);

    mHeaderHeight = (int) (HEADER_HEIGHT_DP * getContext().getResources()
            .getDisplayMetrics().density);

    setHeaderHeight(0);
}

private void setHeaderHeight(final int height) {
    if (height <= 1) {
        mHeaderView.setVisibility(View.GONE);
    } else {
        mHeaderView.setVisibility(View.VISIBLE);
    }

    // Extends refresh bar
    LayoutParams lp = (LayoutParams) mHeaderContainer.getLayoutParams();
    if (lp == null) {
        lp = new LayoutParams(LayoutParams.FILL_PARENT,
                LayoutParams.WRAP_CONTENT);
    }
    lp.height = height;
    mHeaderContainer.setLayoutParams(lp);

    // Refresh bar shows up from bottom to top
    LinearLayout.LayoutParams headerLp = (LinearLayout.LayoutParams) mHeaderView
            .getLayoutParams();
    if (headerLp == null) {
        headerLp = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT,
                LayoutParams.WRAP_CONTENT);
    }

    headerLp.topMargin = -mHeaderHeight + height;

    mHeaderView.setLayoutParams(headerLp);

    if (!mIsRefreshing) {
        // If scroll reaches the trigger line, start refreshing
        if (height > mHeaderHeight && !mArrowUp) {
            mArrow.startAnimation(AnimationUtils.loadAnimation(
                    getContext(), R.anim.rotate));
            mText.setText("Release to update");
            rotateArrow();
            mArrowUp = true;
        } else if (height < mHeaderHeight && mArrowUp) {
            mArrow.startAnimation(AnimationUtils.loadAnimation(
                    getContext(), R.anim.rotate));
            mText.setText("Pull down to update");
            rotateArrow();
            mArrowUp = false;

        } else {

        }
    }
}

private void rotateArrow() {
    Drawable drawable = mArrow.getDrawable();
    Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
            drawable.getIntrinsicHeight(), Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    canvas.save();
    canvas.rotate(180.0f, canvas.getWidth() / 2.0f,
            canvas.getHeight() / 2.0f);
    drawable.setBounds(0, 0, drawable.getIntrinsicWidth(),
            drawable.getIntrinsicHeight());
    drawable.draw(canvas);
    canvas.restore();
    mArrow.setImageBitmap(bitmap);
}

private void startRefreshing() {
    mArrow.setVisibility(View.INVISIBLE);
    mProgress.setVisibility(View.VISIBLE);
    mText.setText("Loading...");
    mIsRefreshing = true;

    if (mListener != null) {
        mListener.onRefresh(this);
    }
    setSelection(0);
}

private final Handler mHandler = new Handler() {

    @Override
    public void handleMessage(final Message msg) {
        super.handleMessage(msg);

        int limit = 0;
        switch (msg.what) {
        case REFRESH:
            limit = mHeaderHeight;
            break;
        case NORMAL:
            limit = 0;
            break;
        }

        // Elastic scrolling
        if (msg.arg1 >= limit) {
            setHeaderHeight(msg.arg1);
            int displacement = (msg.arg1 - limit) / 10;
            if (displacement == 0) {
                mHandler.sendMessage(mHandler.obtainMessage(msg.what,
                        msg.arg1 - 1, 0));
            } else {
                mHandler.sendMessage(mHandler.obtainMessage(msg.what,
                        msg.arg1 - displacement, 0));
            }
        }
    }

};

public interface OnRefreshListener {
    public void onRefresh(RefreshableListView listView);
}

public static interface ListViewObserver {
    public void onScroll(float deltaY);
}
}

在我的代码中,我添加了用于搜索的标题,但是当我添加 ListView 时,向下滚动。 我做了很多调试,但无法弄清楚。

    // Scrolling downward
            if (direction > 0) {
                // Refresh bar is extended if top pixel of the first item is
                // visible
                if (getChildAt(0) != null) {
                    if (getChildAt(0).getTop() == 0) {
                        if (mHistoricalTop < 0) {

                            // mY = ev.getY(); // TODO works without
                            // this?mHistoricalTop = 0;
                        }
                        if (isScrool == true) {

                        } else {
                            isScrool = true;
                            // adding header.
                            addHeaderView(vHeader);

                            Handler hn = new Handler();

                            hn.postDelayed(new Runnable() {

                                @Override
                                public void run() {
                                    // TODO Auto-generated method stub
                                    smoothScrollByOffset(1);

                                }
                            }, 50);
                        }
                        // Extends refresh bar

                        /*****
                         * commented by me on 10-09-2014
                         */
                        Log.e("selected index ",
                                String.valueOf(getScrollY()) + "//"
                                        + getMaxScrollAmount() + "//"
                                        + getAdapter().getCount());
                        setHeaderHeight(height);

                        // Stop list scroll to prevent the list from
                        // overscrolling
                        ev.setAction(MotionEvent.ACTION_CANCEL);
                        mFlag = false;
                    }
                }

最佳答案

我尝试了你的代码并做了一些修改,它对我有用

请检查下面的类

公共(public)类 RefreshableListView 扩展了 ListView {

private TextView search_text;
private Button distance_spinner;
Boolean isScrool = false;
Boolean isFirst = false;
private View mHeaderContainer = null;
private View mHeaderView = null;
private ImageView mArrow = null;
private ProgressBar mProgress = null;
private TextView mText = null;
private float mY = 0;
private float mHistoricalY = 0;
private int mHistoricalTop = 0;
private int mInitialHeight = 0;
private boolean mFlag = false;
private boolean mArrowUp = false;
private boolean mIsRefreshing = false;
private int mHeaderHeight = 0;
private OnRefreshListener mListener = null;

private static final int REFRESH = 0;
private static final int NORMAL = 1;
private static final int HEADER_HEIGHT_DP = 62;
@SuppressWarnings("unused")
private static final String TAG = RefreshableListView.class.getSimpleName();

OnTouchListener touch;

public static View vHeader;
View vheaders;

public RefreshableListView(final Context context) {
    super(context);
    initialize();
}

public RefreshableListView(final Context context, final AttributeSet attrs) {
    super(context, attrs);
    initialize();
}

public RefreshableListView(final Context context, final AttributeSet attrs,
        final int defStyle) {
    super(context, attrs, defStyle);
    initialize();
}

public void setOnRefreshListener(final OnRefreshListener l) {
    mListener = l;
}

@Override
public void setOnTouchListener(OnTouchListener l) {
    super.setOnTouchListener(l);
}

public void completeRefreshing() {
    mProgress.setVisibility(View.INVISIBLE);
    mArrow.setVisibility(View.VISIBLE);
    mHandler.sendMessage(mHandler.obtainMessage(NORMAL, mHeaderHeight, 0));
    mIsRefreshing = false;
    invalidateViews();
}

@Override
public boolean onInterceptTouchEvent(final MotionEvent ev) {
    switch (ev.getAction()) {
    case MotionEvent.ACTION_DOWN:
        mHandler.removeMessages(REFRESH);
        mHandler.removeMessages(NORMAL);
        mY = mHistoricalY = ev.getY();
        if (mHeaderContainer.getLayoutParams() != null) {
            mInitialHeight = mHeaderContainer.getLayoutParams().height;
        }

        break;
    }
    return super.onInterceptTouchEvent(ev);
}

@Override
public boolean onTouchEvent(final MotionEvent ev) {
    switch (ev.getAction()) {
    case MotionEvent.ACTION_MOVE:
        mHistoricalTop = getChildAt(0).getTop();
        break;
    case MotionEvent.ACTION_UP:
        if (!mIsRefreshing) {
            if (mArrowUp) {
                startRefreshing();
                mHandler.sendMessage(mHandler.obtainMessage(REFRESH,
                        (int) (ev.getY() - mY) / 2 + mInitialHeight, 0));
            } else {
                if (getChildAt(0).getTop() == 0) {
                    mHandler.sendMessage(mHandler.obtainMessage(NORMAL,
                            (int) (ev.getY() - mY) / 2 + mInitialHeight, 0));
                }
            }
        } else {
            mHandler.sendMessage(mHandler.obtainMessage(REFRESH,
                    (int) (ev.getY() - mY) / 2 + mInitialHeight, 0));
        }
        mFlag = false;
        break;

    }
    return super.onTouchEvent(ev);
}

@Override
public boolean dispatchTouchEvent(final MotionEvent ev) {
    if (ev.getAction() == MotionEvent.ACTION_MOVE
            && getFirstVisiblePosition() == 0) {
        float direction = ev.getY() - mHistoricalY;
        int height = (int) (ev.getY() - mY) / 2 + mInitialHeight;
        if (height < 0) {
            height = 0;
        }

        float deltaY = Math.abs(mY - ev.getY());
        ViewConfiguration config = ViewConfiguration.get(getContext());
        if (deltaY > config.getScaledTouchSlop()) {

            // Scrolling downward
            if (direction > 0) {
                // Refresh bar is extended if top pixel of the first item is
                // visible
                if (getChildAt(0) != null) {
                    if (getChildAt(0).getTop() == 0) {
                        if (mHistoricalTop < 0) {

                            // mY = ev.getY();
                            // this?mHistoricalTop = 0;
                        }

                        // Animation anim =
                        // AnimationUtils.loadAnimation(
                        // getContext(), R.anim.bounce_animation);
                        // startAnimation(anim);
                        // setSelectionAfterHeaderView();
                        // setOverScrollMode(View.OVER_SCROLL_NEVER);
                        // setSelectionFromTop(0, 0);
                        // smoothScrollToPosition(getChildAt(0).getTop()
                        // - vHeader.getHeight());
                        // bottom_layout.setVisibility(View.VISIBLE);
                        // }
                        // Extends refresh bar
                        if (isScrool == true) {

                            if (search_text.getVisibility() == 0
                                    && distance_spinner.getVisibility() == 0) {

                            } else {
                                search_text.setVisibility(View.VISIBLE);
                                distance_spinner
                                        .setVisibility(View.VISIBLE);
                            }
                        } else {
                            isScrool = true;
                            // Extends refresh bar

                            search_text.setVisibility(View.VISIBLE);
                            distance_spinner.setVisibility(View.VISIBLE);

                        }

                        setHeaderHeight(height);

                        // Stop list scroll to prevent the list from
                        // overscrolling
                        ev.setAction(MotionEvent.ACTION_CANCEL);
                        mFlag = false;
                    }
                }

            } else if (direction < 0) {
                // Scrolling upward

                // Refresh bar is shortened if top pixel of the first item
                // is
                // visible
                if (getChildAt(0) != null) {
                    if (getChildAt(0).getTop() == 0) {
                        setHeaderHeight(height);

                        // If scroll reaches top of the list, list scroll is
                        // enabled
                        if (getChildAt(1) != null
                                && getChildAt(1).getTop() <= 1 && !mFlag) {
                            ev.setAction(MotionEvent.ACTION_DOWN);
                            mFlag = true;
                        }
                    }
                }
            }
        }

        mHistoricalY = ev.getY();
    }
    try {
        return super.dispatchTouchEvent(ev);
    } catch (Exception e) {
        return false;
    }
}

@Override
public boolean performItemClick(final View view, final int position,
        final long id) {
    if (position == 0) {
        // This is the refresh header element
        return true;
    } else {
        return super.performItemClick(view, position - 1, id);
    }
}

private void initialize() {

    LayoutInflater inflator = (LayoutInflater) getContext()
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    vHeader = inflator.inflate(R.layout.search_header, null);
    LayoutInflater inflater = (LayoutInflater) getContext()
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    mHeaderContainer = inflater.inflate(R.layout.refreshable_list_header,
            null);
    vheaders = vHeader.findViewById(R.id.search_layout);

    mHeaderView = mHeaderContainer
            .findViewById(R.id.refreshable_list_header);
    mArrow = (ImageView) mHeaderContainer
            .findViewById(R.id.refreshable_list_arrow);
    mProgress = (ProgressBar) mHeaderContainer
            .findViewById(R.id.refreshable_list_progress);
    mText = (TextView) mHeaderContainer
            .findViewById(R.id.refreshable_list_text);
    addHeaderView(mHeaderContainer);

    search_text = (TextView) vheaders.findViewById(R.id.editText1);
    distance_spinner = (Button) vheaders.findViewById(R.id.button1);
    search_text.setVisibility(View.GONE);
    distance_spinner.setVisibility(View.GONE);
    addHeaderView(vheaders);

    mHeaderHeight = (int) (HEADER_HEIGHT_DP * getContext().getResources()
            .getDisplayMetrics().density);

    setHeaderHeight(0);
}

public View getHeaderview() {
    return vHeader;

}

private void setHeaderHeight(final int height) {
    if (height <= 1) {
        mHeaderView.setVisibility(View.GONE);
    } else {
        mHeaderView.setVisibility(View.VISIBLE);

    }

    // Extends refresh bar
    LayoutParams lp = (LayoutParams) mHeaderContainer.getLayoutParams();
    if (lp == null) {
        lp = new LayoutParams(LayoutParams.MATCH_PARENT,
                LayoutParams.WRAP_CONTENT);
    }
    lp.height = height;
    mHeaderContainer.setLayoutParams(lp);

    // Refresh bar shows up from bottom to top
    LinearLayout.LayoutParams headerLp = (LinearLayout.LayoutParams) mHeaderView
            .getLayoutParams();
    if (headerLp == null) {
        headerLp = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,
                LayoutParams.WRAP_CONTENT);
    }

    headerLp.topMargin = -mHeaderHeight + height;

    mHeaderView.setLayoutParams(headerLp);

    if (!mIsRefreshing) {
        // If scroll reaches the trigger line, start refreshing
        if (height > mHeaderHeight && !mArrowUp) {
            mArrow.startAnimation(AnimationUtils.loadAnimation(
                    getContext(), R.anim.rotate));
            mText.setText("Release to update");
            rotateArrow();
            mArrowUp = true;
        } else if (height < mHeaderHeight && mArrowUp) {
            mArrow.startAnimation(AnimationUtils.loadAnimation(
                    getContext(), R.anim.rotate));
            mText.setText("Pull down to update");
            rotateArrow();
            mArrowUp = false;

        } else {

        }
    }
}

private void rotateArrow() {
    Drawable drawable = mArrow.getDrawable();
    Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
            drawable.getIntrinsicHeight(), Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    canvas.save();
    canvas.rotate(180.0f, canvas.getWidth() / 2.0f,
            canvas.getHeight() / 2.0f);
    drawable.setBounds(0, 0, drawable.getIntrinsicWidth(),
            drawable.getIntrinsicHeight());
    drawable.draw(canvas);
    canvas.restore();
    mArrow.setImageBitmap(bitmap);
}

public void startRefreshing() {
    mArrow.setVisibility(View.INVISIBLE);
    mProgress.setVisibility(View.VISIBLE);
    mText.setText("Loading...");
    mIsRefreshing = true;

    if (mListener != null) {
        mListener.onRefresh(this);
    }
    setSelection(0);
}

private final Handler mHandler = new Handler() {

    @Override
    public void handleMessage(final Message msg) {
        super.handleMessage(msg);

        int limit = 0;
        switch (msg.what) {
        case REFRESH:
            limit = mHeaderHeight;
            break;
        case NORMAL:
            limit = 0;
            break;
        }

        // Elastic scrolling
        if (msg.arg1 >= limit) {
            setHeaderHeight(msg.arg1);
            int displacement = (msg.arg1 - limit) / 10;
            if (displacement == 0) {
                mHandler.sendMessage(mHandler.obtainMessage(msg.what,
                        msg.arg1 - 1, 0));
            } else {
                mHandler.sendMessage(mHandler.obtainMessage(msg.what,
                        msg.arg1 - displacement, 0));
            }
        }
    }

};

public interface OnRefreshListener {
    public void onRefresh(RefreshableListView listView);
}

public static interface ListViewObserver {
    public void onScroll(float deltaY);
}

关于android - Listview 拉动刷新库并添加标题 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25806397/

相关文章:

android - 当鼠标移开时关闭 IntelliJ 文档 (quick-doc) 窗口

android - 如何访问Android设备的根文件夹(/)的数据?

asp.net - 如何处理 ListView 按钮中的onclick事件?

listview - ListView 在 React Native + Redux 应用中的表现

android - 我想测量 ListView 的高度(getHight() = 0)

java - 将项目添加到 Android ListView

android - 如何从适配器访问 ListView

android - 在 Android O 预览中将 AdaptiveIconDrawable 转换为位图

java - 如何缩放 Android TableLayout

android listview 滑动删除就像在 gmail 应用程序中一样