自定義SlideRefreshListView

這裏寫圖片描述

public class SlideRefreshListView extends ListView implements AbsListView.OnScrollListener{

    private View header;
    private ImageView arrow;
    private ProgressBar progressBar;
    private TextView content;
    private TextView time;
    private float downY;
    private float moveY;
    private int mHeaderHeight;
    //箭頭上滑動畫
    private RotateAnimation rotateUpAnimation;
    //箭頭下滑動畫
    private RotateAnimation rotateDowmAnimation;
    //下拉刷新
    public static final int PULL_TO_REFRESH = 0;
    //釋放刷新
    public static final int RELEASE_REFRESH = 1;
    //正在刷新中
    public static final int REFRESHING = 2;
    //當前刷新模式
    private int currentState = PULL_TO_REFRESH;
    //刷新監聽用於接收具體實現
    private OnRefreshListener onRefreshListener;
    //是否在加載更多 默認沒有加載更多
    boolean isLoadMore = false;
    private View footer;
    private int mFooterHeight;

    //刷新完成狀態
    public static final int REFRESH = 0;
    //加載更多完成狀態
    public static final int LOAD_MORE = 1;

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

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

    public SlideRefreshListView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    //初始化
    private void init() {
        initHeader();
        initFooter();
        initAnim();
        setOnScrollListener(this);
    }

    //初始化頭佈局
    private void initHeader() {
        header = View.inflate(getContext(), R.layout.layout_header, null);

        arrow = (ImageView) header.findViewById(R.id.arrow);
        progressBar = (ProgressBar) header.findViewById(R.id.progressBar);
        content = (TextView) header.findViewById(R.id.tv_content);
        time = (TextView) header.findViewById(R.id.tv_time);

        header.measure(0, 0);
        mHeaderHeight = header.getMeasuredHeight();
        //初始化隱藏頭佈局
        header.setPadding(0, -mHeaderHeight, 0, 0);
        addHeaderView(header);
    }

    //初始化腳佈局
    private void initFooter() {

        footer = View.inflate(getContext(), R.layout.layout_footer, null);
        //先測量再拿高度
        footer.measure(0, 0);
        mFooterHeight = footer.getMeasuredHeight();
        //初始化隱藏腳佈局
        footer.setPadding(0, -mFooterHeight, 0, 0);
        addFooterView(footer);
    }

    //初始化動畫 箭頭旋轉
    private void initAnim() {
        //逆時針 0->-180
        rotateUpAnimation = new RotateAnimation(0, -180f,
                Animation.RELATIVE_TO_SELF, 0.5f,
                Animation.RELATIVE_TO_SELF, 0.5f);
        //持續時間
        rotateUpAnimation.setDuration(200);
        //動畫結束後保持位置
        rotateUpAnimation.setFillAfter(true);
        rotateDowmAnimation = new RotateAnimation(-180, -360f,
                Animation.RELATIVE_TO_SELF, 0.5f,
                Animation.RELATIVE_TO_SELF, 0.5f);
        rotateDowmAnimation.setDuration(200);
        rotateDowmAnimation.setFillAfter(true);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                downY = ev.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                moveY = ev.getY();

                //如果當前已經在刷新 則將事件交由父親去處理
                if (currentState == REFRESHING) {
                    return super.onTouchEvent(ev);
                }

                float dy = moveY - downY; // 移動的偏移量
                // 當dy>0 且頭佈局可見時才改變頭佈局的padding
                if (dy > 0 && getFirstVisiblePosition() == 0) {
                    int paddingTop = (int) (-mHeaderHeight + 0.4 * dy);

                    header.setPadding(0, paddingTop, 0, 0);

                    //佈局完全顯示
                    if (paddingTop >= 0 && currentState != RELEASE_REFRESH) {
                        currentState = RELEASE_REFRESH;
                        updateHeader();
                    } else if (paddingTop < 0 && currentState != PULL_TO_REFRESH) {
                        //佈局不完全顯示
                        currentState = PULL_TO_REFRESH;
                        updateHeader();
                    }

                    return true;
                }
                break;

            case MotionEvent.ACTION_UP:
                //還沒滑到位 鬆開隱藏頭佈局
                if (currentState == PULL_TO_REFRESH) {
                    header.setPadding(0, -mHeaderHeight, 0, 0);
                } else if (currentState == RELEASE_REFRESH) {
                    //設置當前狀態爲REFRESHING 避免重複進入
                    currentState = REFRESHING;
                    //滑到位了 全部顯示頭佈局
                    header.setPadding(0, 0, 0, 0);
                    updateHeader();
                }

                break;
        }

        return super.onTouchEvent(ev);

    }

    //根據currentState更新頭佈局
    private void updateHeader() {
        switch (currentState) {
            case PULL_TO_REFRESH:
                arrow.startAnimation(rotateUpAnimation);
                content.setText("下拉刷新...");
                break;
            case RELEASE_REFRESH:
                arrow.startAnimation(rotateDowmAnimation);
                content.setText("釋放刷新...");

                break;
            case REFRESHING:

                //只有清除綁定的動畫 才能設置不可見
                arrow.clearAnimation();
                arrow.setVisibility(View.INVISIBLE);
                progressBar.setVisibility(View.VISIBLE);
                content.setText("正在刷新...");

                if(onRefreshListener != null) {
                    onRefreshListener.onRefresh();
                }

                break;
            default:
                break;
        }
    }

    @Override
    public void onScrollStateChanged(AbsListView absListView, int scrollState) {

        if(isLoadMore){
            return;
        }
        // 最新狀態是空閒狀態, 並且當前界面顯示了所有數據的最後一條. 加載更多
        if(scrollState == SCROLL_STATE_IDLE && getLastVisiblePosition() >= (getCount() - 1)){
            isLoadMore = true;
            footer.setPadding(0, 0, 0, 0);

            setSelection(getCount()); // 跳轉到最後一條, 使其顯示出加載更多.

            if(onRefreshListener != null){
                onRefreshListener.onLoadMore();
            }
        }
    }

    @Override
    public void onScroll(AbsListView absListView, int i, int i1, int i2) {

    }

    // 獲取當前時間
    private String getRefreshTime(){
        long current = System.currentTimeMillis();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
        return sdf.format(current);
    }


    public void RefreshComplete(int state){
        switch (state){
            case REFRESH:
                currentState = PULL_TO_REFRESH;
                content.setText("下拉刷新...");
                header.setPadding(0,-mHeaderHeight,0,0);
                arrow.setVisibility(VISIBLE);
                progressBar.setVisibility(View.VISIBLE);
                String ctime = getRefreshTime();
                time.setText("上次刷新時間: " + time);

                break;
            case LOAD_MORE:
                footer.setPadding(0, -mFooterHeight, 0, 0);
                isLoadMore = false;
                break;
        }
    }

    /**
     * 刷新回調接口
     */
    public interface OnRefreshListener{
        void onRefresh();
        void onLoadMore();
    }

    /**
     * 設置監聽
     * @param orl
     */
    public void setOnRefreshListener(OnRefreshListener orl){
        this.onRefreshListener = orl;
    }
}

MainActivity

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final SlideRefreshListView listView = (SlideRefreshListView) findViewById(R.id.srListView);
        listView.setOnRefreshListener(new SlideRefreshListView.OnRefreshListener() {
            @Override
            public void onRefresh() {
                // TODO: 2017/3/15 刷新邏輯

            }

            @Override
            public void onLoadMore() {
                // TODO: 2017/3/15 加載更多
                new Thread(){
                    @Override
                    public void run() {

                        try {
                            Thread.sleep(2000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        list.add("加載更多出來的數據****");

                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                listView.RefreshComplete(SlideRefreshListView.LOAD_MORE);
                                lvAdapter.notifyDataSetChanged();
                            }
                        });
                    }
                }.start();
                //這裏我開始愚蠢的用成了.run() 然後手機卡到爆由於時間沒到5s沒有報ANR

            }
        });

        list = new ArrayList<>();
        for(int i=0;i<30;i++)
            list.add(i,"這是假數據"+i);
        lvAdapter = new LVAdapter();
        listView.setAdapter(lvAdapter);
    }
    class LVAdapter extends BaseAdapter{

        @Override
        public int getCount() {
            return list.size();
        }

        @Override
        public Object getItem(int i) {
            return null;
        }

        @Override
        public long getItemId(int i) {
            return 0;
        }

        @Override
        public View getView(int position, View view, ViewGroup parent) {
            TextView textView = new TextView(parent.getContext());
            textView.setTextSize(18f);
            textView.setText(list.get(position));

            return textView;
        }
    }

https://github.com/REIGE/SlideRefreshListView

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章