ListView的上拉弹簧、下拉弹簧,下拉弹簧时动态带刷新和切换换刷新视图

来源:互联网 发布:矫饰 知乎 编辑:程序博客网 时间:2024/04/29 20:43

重写继承ListView后,其实本质就是两点:

(1)弹簧:利用View的scrollTo(int x, int y)方法来搞定弹簧;

(2)动态的加入和删除Header;

(3)Scroller滚动的方向和手指滑动的方向是相反的。

下面是 例子:

(1)MainActivity.class

package com.habby.sliderbar;import java.util.ArrayList;import java.util.List;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.util.Log;import android.view.LayoutInflater;import android.view.View;import android.view.View.OnClickListener;import android.widget.ArrayAdapter;import com.habby.sliderbar.SpringListView.SpringListener;public class MainActivity extends Activity implements OnClickListener {    private final String TAG = getClass().getSimpleName();    private final int COMPLETED = 1; // 已完成    private SpringListView mListView = null;    private SpringListener mSpringListener = null;    private List<String> mDatas;    private ArrayAdapter<String> mAdapter;    private View mHeader1 = null;    private View mHeader2 = null;    private Handler mListener = new Handler() {        @Override        public void handleMessage(Message msg) {            if (msg.what == COMPLETED) {                if (mListView.getHeaderViewsCount() != 0) {                    mListView.removeHeaderView(mHeader2);                }            }        }    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initView();    }    @Override    public void onClick(View view) {        switch (view.getId()) {        default:            break;        }    }    private void initView() {        mListView = (SpringListView) findViewById(R.id.name_lv);        mDatas = new ArrayList<String>();        for (int i = 0; i < 25; ++i) {            mDatas.add("fuck you");        }        mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mDatas);        mHeader1 = LayoutInflater.from(this).inflate(R.layout.slider_view, null);        mHeader2 = LayoutInflater.from(this).inflate(R.layout.right_view, null);        /**         * 这应该是一个bug,必须在setAdapter之前addHeaderView,然后再removeHeaderView,这         * 样才能动态的加入和删除header。         */        mListView.addHeaderView(mHeader1);        mListView.setAdapter(mAdapter);        mListView.removeHeaderView(mHeader1);        mSpringListener = new SpringListener() {            @Override            public void onSpringUpPush() {                Log.e(TAG, "UpPush !");            }            @Override            public void onSpringDownPush() {                Log.e(TAG, "DownPush");                if (mListView.getHeaderViewsCount() == 0) {                    mListView.addHeaderView(mHeader1);                }            }            @Override            public void onSpringCompleted() {                Log.e(TAG, "Completed !");                if (mListView.getHeaderViewsCount() != 0) {                    mListView.removeHeaderView(mHeader1);                    mListView.addHeaderView(mHeader2);                    mListener.obtainMessage(COMPLETED).sendToTarget();                }            }        };        mListView.registerSpringListener(mSpringListener);    }}


(2)SpringListView.class

package com.habby.sliderbar;import android.content.Context;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.widget.ListView;/** * 针对一个带上拉/下拉弹簧效果的ListView,比普通的ListView仅仅多了弹簧效果而已; * 因此,可以重写ListView,添加弹簧效果即可,其他的行为依旧是默认的ListView行为。 * 子线程用于处理 “弹回” 效果。 * @author habby */public class SpringListView extends ListView implements Runnable {    private float mLastDownY = 0f;    private int mDistance = 0;    // 手指/弹簧拉去移动的距离    private int mStep = 10;    private boolean mPositive = false; // 滚动方向    private SpringListener mListener;    public SpringListView(Context ctx, AttributeSet attrs) {        super(ctx, attrs);    }        public SpringListView(Context ctx, AttributeSet attrs, int defStyle) {        super(ctx, attrs, defStyle);    }    public SpringListView(Context ctx) {        super(ctx);    }    @Override    public void onFinishInflate() {    }    /**     * 只有满足这个情况才会有下拉弹簧:     * 当按下时,ListView可以显示的第1行是处于顶部第1个或底部最后1个时,下拉或上拉才有弹簧效果。     */    @Override    public boolean onTouchEvent(MotionEvent event) {        switch (event.getAction()) {        case MotionEvent.ACTION_DOWN:            if (getFirstVisiblePosition() == 0 || getLastVisiblePosition() == getCount() - 1) {                mLastDownY = event.getY();                return true;            }            mDistance = 0;            break;        case MotionEvent.ACTION_MOVE:// 拉伸            mDistance = (int) (mLastDownY - event.getY());            if ((mDistance < 0 && (getFirstVisiblePosition() == 0)) || (mDistance > 0 && (getLastVisiblePosition() == getCount() - 1))) {                mDistance /= 2;                scrollTo(0, mDistance);                if (mListener != null) {                    if (mDistance < 0) {                        mListener.onSpringDownPush();                    } else if (mDistance > 0) {                        mListener.onSpringUpPush();                    }                }                return true;            }            mDistance = 0;            break;        case MotionEvent.ACTION_UP:// 松手的时候,弹回来            if ((mDistance < 0 && getFirstVisiblePosition() == 0) || (mDistance > 0 && getLastVisiblePosition() == getCount() - 1)) {                mStep = 1;                mPositive = (mDistance >= 0);                this.post(this);// 启动子线程,用于 "弹回" 效果                return true;            }            mDistance = 0;            break;        default:            break;        }        // 其他情况使用ListView(父类)本身的行为,不覆盖。这里仅仅是覆盖了ListView以上的2中情况。        return super.onTouchEvent(event);    }    @Override    public void run() {        mDistance += mDistance > 0 ? -mStep : mStep;        scrollTo(0, mDistance);        if ((mPositive && mDistance <= 0) || (!mPositive && mDistance >= 0)) {            scrollTo(0, 0);            mDistance = 0;            mLastDownY = 0f;            if (mListener != null) {                mListener.onSpringCompleted();            }            return;        }        mStep += 5;        this.postDelayed(this, 10);    }    public void registerSpringListener(SpringListener listener) {        mListener = listener;    }    /**     * 回调接口     */    public interface SpringListener {        public void onSpringDownPush();// 下拉        public void onSpringUpPush();// 上拉        public void onSpringCompleted();//"回弹" 完成    }}