ListView的上拉下拉

package cn.juzhong.view.widget;

import cn.juzhong.R;
import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.*;
import android.widget.AbsListView.OnScrollListener;

/**
* 拖拉ListView
* Created by dudc on 14-4-18.
*
* @author dudc
*/
public class PullListView extends ListView implements OnScrollListener,
OnClickListener {

/**
 * 加载数据包
 */
public static final int LOADDATA_INDEX = 0;
/**
 * 下拉刷新标识
 */
public static final int DRAG_INDEX = 1;
/**
 * 加载更多标识
 */
public static final int LOADMORE_INDEX = 2;
/**
 * 刷新
 */
public static final int REFRESH_INDEX = 3;
public static final int PAGEDATA_COUNT = 20;

private enum DListViewState {
    LV_NORMAL,
    LV_PULL_REFRESH,
    LV_RELEASE_REFRESH,
    LV_LOADING;
}

private enum DListViewLoadingMore {
    LV_NORMAL,
    LV_LOADING,
    LV_OVER;
}

private View mHeadView;
private TextView mRefreshTextview;
private TextView mLastUpdateTextView;
private ImageView mArrowImageView;
private ProgressBar mHeadProgressBar;
private View mHeadHorLineView;

private int mHeadViewWidth;
private int mHeadViewHeight;

private View mFootView;
private View mLoadMoreView;
private TextView mLoadMoreTextView;
private View mLoadingView;

private View mEmptyView;
private TextView mEmptyText;

private Animation animation, reverseAnimation;

private int mFirstItemIndex = -1;

private int mLastItemIndex;

private boolean mIsRecord = false;

private int mStartY, mMoveY;

private DListViewState mlistViewState = DListViewState.LV_NORMAL;

private DListViewLoadingMore loadingMoreState = DListViewLoadingMore.LV_NORMAL;

private final static int RATIO = 2;

private boolean mBack = false;

private OnFooterRefreshListener mOnFooterRefreshListener;
private OnHeaderRefreshListener mOnHeaderRefreshListener;

private boolean isScroller = true;

private boolean isclick = true;

public PullListView(Context context) {
    super(context, null);
    initDragListView(context);
}

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

/**
 * 初始化ListView
 */
public void initDragListView(Context context) {

    /*String time = "";

    initHeadView(context, time);

*/
// initLoadMoreView(context);// 初始化footer

    initEmptyView(context);
    setOnScrollListener(this);
}

/**
 * 初始话头部
 *
 * @param context
 * @param time
 */
public void initHeadView(Context context, String time) {
    mHeadView = LayoutInflater.from(context).inflate(R.layout.activity_pull_header, null);
    mArrowImageView = (ImageView) mHeadView
            .findViewById(R.id.head_arrowImageView);
    mArrowImageView.setMinimumWidth(60);

    mHeadProgressBar = (ProgressBar) mHeadView
            .findViewById(R.id.head_progressBar);

    mRefreshTextview = (TextView) mHeadView
            .findViewById(R.id.head_tipsTextView);

    mHeadHorLineView = mHeadView
            .findViewById(R.id.head_horLineView);

    mLastUpdateTextView = (TextView) mHeadView
            .findViewById(R.id.head_lastUpdatedTextView);

    mLastUpdateTextView.setText("最近更新:" + time);

    measureView(mHeadView);

    mHeadViewWidth = mHeadView.getMeasuredWidth();
    mHeadViewHeight = mHeadView.getMeasuredHeight();

    addHeaderView(mHeadView, null, false);
    mHeadView.setPadding(0, -1 * mHeadViewHeight, 0, 0);

    initAnimation();// 初始化动画
}

/**
 * Resets the list to a normal state after a refresh.
 *
 * @param lastUpdated Last updated at.
 */
public void onHeaderRefreshComplete(CharSequence lastUpdated) {
    setLastUpdated(lastUpdated);
    onRefreshComplete();
}

/**
 * Set a text to represent when the list was last updated.
 *
 * @param lastUpdated Last updated at.
 */
public void setLastUpdated(CharSequence lastUpdated) {
    if (lastUpdated != null) {
        mLastUpdateTextView.setVisibility(View.VISIBLE);
        mLastUpdateTextView.setText(lastUpdated);
    } else {
        mLastUpdateTextView.setVisibility(View.GONE);
    }
}


/**
 * 初始化底部
 */
private void initLoadMoreView(Context context) {
    mFootView = LayoutInflater.from(context).inflate(R.layout.activity_pull_footer, null);

    mLoadMoreView = mFootView.findViewById(R.id.load_more_view);

    mLoadMoreTextView = (TextView) mFootView
            .findViewById(R.id.load_more_tv);

    mLoadingView = (LinearLayout) mFootView
            .findViewById(R.id.loading_layout);

    mLoadMoreView.setOnClickListener(this);

    addFooterView(mFootView);
}

/**
 * 初始化动画
 */
private void initAnimation() {
    animation = new RotateAnimation(0, -180,
            RotateAnimation.RELATIVE_TO_SELF, 0.5f,
            RotateAnimation.RELATIVE_TO_SELF, 0.5f);
    animation.setInterpolator(new LinearInterpolator());
    animation.setDuration(250);
    animation.setFillAfter(true);
    //
    reverseAnimation = new RotateAnimation(-180, 0,
            RotateAnimation.RELATIVE_TO_SELF, 0.5f,
            RotateAnimation.RELATIVE_TO_SELF, 0.5f);
    reverseAnimation.setInterpolator(new LinearInterpolator());
    reverseAnimation.setDuration(250);
    reverseAnimation.setFillAfter(true);
}

/**
 * headVie.
 *
 * @param child
 */
private void measureView(View child) {
    ViewGroup.LayoutParams p = child.getLayoutParams();
    if (p == null) {
        p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_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);
}

/**
 * touch
 */
@Override
public boolean onTouchEvent(MotionEvent ev) throws NullPointerException {
    float xDown = 0.0f;
    float xMove;
    switch (ev.getAction()) {
        // 按下
        case MotionEvent.ACTION_DOWN:
            xDown = ev.getRawX();
            isclick = true;
            isCick();
            doActionDown(ev);
            break;
        // 移动
        case MotionEvent.ACTION_MOVE:
            xMove = ev.getRawX();
            if (xMove - xDown > 420) {
                isclick = false;
            }
            isCick();
            doActionMove(ev);

            break;
        // 抬起
        case MotionEvent.ACTION_UP:
            doActionUp(ev);
            break;
        default:
            break;
    }


    if (isScroller) {
        return super.onTouchEvent(ev);
    } else {
        return true;
    }

}

/**
 * 摁下操作
 * <p/>
 * 作用:获取摁下是的y坐标
 *
 * @param event
 */
void doActionDown(MotionEvent event) {
    if (mIsRecord == false && mFirstItemIndex == 0) {
        mStartY = (int) event.getY();
        mIsRecord = true;
    }
}

/**
 * 拖拽移动操作
 *
 * @param event
 */
void doActionMove(MotionEvent event) {
    mMoveY = (int) event.getY();
    // 检测是否是一次touch事件.
    if (mIsRecord == false && mFirstItemIndex == 0) {
        mStartY = (int) event.getY();
        mIsRecord = true;
    }
    /***
     *  return.
     */
    if (mIsRecord == false || mlistViewState == DListViewState.LV_LOADING) {
        return;
    }

    int offset = (mMoveY - mStartY) / RATIO;
    if (mHeadView != null) {
        switch (mlistViewState) {
            // 普通状态
            case LV_NORMAL: {

                if (offset > 0) {
                    // 设置headView的padding属性.
                    mHeadView.setPadding(0, offset - mHeadViewHeight, 0, 0);
                    switchViewState(DListViewState.LV_PULL_REFRESH);// 下拉状态
                }

            }
            break;
            // 下拉状态
            case LV_PULL_REFRESH: {
                setSelection(0);// 选中第一项,可选.

                mHeadView.setPadding(0, offset - mHeadViewHeight, 0, 0);
                if (offset < 0) {
                    /***
                     * 要明白为什么isScroller = false;
                     */
                    isScroller = false;
                    switchViewState(DListViewState.LV_NORMAL);
                    Log.e("jj", "isScroller=" + isScroller);
                } else if (offset > mHeadViewHeight) {
                    switchViewState(DListViewState.LV_RELEASE_REFRESH);
                }
            }
            break;
            // 可刷新状态
            case LV_RELEASE_REFRESH: {
                setSelection(0);
                // 设置headView的padding属性.
                mHeadView.setPadding(0, offset - mHeadViewHeight, 0, 0);

                if (offset >= 0 && offset <= mHeadViewHeight) {
                    mBack = true;
                    switchViewState(DListViewState.LV_PULL_REFRESH);
                } else if (offset < 0) {
                    switchViewState(DListViewState.LV_NORMAL);
                } else {

                }
            }
            break;
            default:
                return;
        }
        ;
    }
}

/**
 * 手势抬起操作
 *
 * @param event
 */
@SuppressWarnings({"static-access", "incomplete-switch"})
public void doActionUp(MotionEvent event) {
    mIsRecord = false;
    isScroller = true;
    mBack = false;

    if (mlistViewState == DListViewState.LV_LOADING) {
        return;
    }
    // 处理相应状态.
    switch (mlistViewState) {
        case LV_NORMAL:

            break;
        case LV_PULL_REFRESH:
            mHeadView.setPadding(0, -1 * mHeadViewHeight, 0, 0);
            switchViewState(mlistViewState.LV_NORMAL);
            break;
        case LV_RELEASE_REFRESH:
            mHeadView.setPadding(0, 0, 0, 0);
            switchViewState(mlistViewState.LV_LOADING);
            onRefresh();// 下拉刷新
            break;
    }

}

// 切换headview视图
private void switchViewState(DListViewState state) {

    switch (state) {
        // 普通状态
        case LV_NORMAL: {
            mArrowImageView.clearAnimation();// 清除动画
            mArrowImageView.setImageResource(R.drawable.pull_arrow);
        }
        break;
        // 下拉状态
        case LV_PULL_REFRESH: {
            mHeadProgressBar.setVisibility(View.GONE);// 隐藏进度条
            mArrowImageView.setVisibility(View.VISIBLE);// 下拉图标
            mRefreshTextview.setText("下拉刷新");
            mArrowImageView.clearAnimation();// 清除动画

            if (mBack) {
                mBack = false;
                mArrowImageView.clearAnimation();// 清除动画
                mArrowImageView.startAnimation(reverseAnimation);// 启动反转动画
            }
        }
        break;
        // 松开刷新状态
        case LV_RELEASE_REFRESH: {
            mHeadProgressBar.setVisibility(View.GONE);// 隐藏进度条
            mArrowImageView.setVisibility(View.VISIBLE);// 显示下拉图标
            mRefreshTextview.setText("释放立即刷新");
            mArrowImageView.clearAnimation();// 清除动画
            mArrowImageView.startAnimation(animation);// 启动动画
        }
        break;
        // 加载状态
        case LV_LOADING: {
            Log.e("!!!!!!!!!!!", "convert to IListViewState.LVS_LOADING");
            mHeadProgressBar.setVisibility(View.VISIBLE);
            mArrowImageView.clearAnimation();
            mArrowImageView.setVisibility(View.GONE);
            mRefreshTextview.setText("正在刷新...");
        }
        break;
        default:
            return;
    }
    // 切记不要忘记时时更新状态。
    mlistViewState = state;

}

/**
 * 下拉刷新
 */
private void onRefresh() {
    if (mOnHeaderRefreshListener != null) {
        mOnHeaderRefreshListener.onRefresh();
    }
}

/**
 * 下拉刷新完毕
 */
@SuppressWarnings("static-access")
public void onRefreshComplete() {
    mHeadView.setPadding(0, -1 * mHeadViewHeight, 0, 0);// 回归.
    switchViewState(mlistViewState.LV_NORMAL);//
}

/**
 * 点击加载更多
 *
 * @param flag 数据是否已全部加载完毕
 */
public void onLoadMoreComplete(boolean flag) {
    if (flag) {
        updateLoadMoreViewState(DListViewLoadingMore.LV_OVER);
        //  removeFooterView(mFootView);
    } else {
        updateLoadMoreViewState(DListViewLoadingMore.LV_NORMAL);
    }

}

// 更新Footview视图
private void updateLoadMoreViewState(DListViewLoadingMore state) {
    if (mLoadingView != null) {
        switch (state) {
            // 普通状态
            case LV_NORMAL:
                mLoadingView.setVisibility(View.GONE);
                mLoadMoreTextView.setVisibility(View.VISIBLE);
                mLoadMoreTextView.setText("查看更多");
                break;
            // 加载中状态
            case LV_LOADING:
                mLoadMoreTextView.setVisibility(View.GONE);
                mLoadingView.setVisibility(View.VISIBLE);
                break;
            // 加载完毕状态
            case LV_OVER:
                mLoadingView.setVisibility(View.GONE);
                mLoadMoreTextView.setVisibility(View.GONE);

// mLoadMoreTextView.setVisibility(View.VISIBLE);
// mLoadMoreTextView.setText(“没有更多了”);
break;
default:
break;
}
loadingMoreState = state;
}
}

/**
 * ListView 滑动监听
 */
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
    int itemsLastIndex = view.getCount() - 1;
    //  int lastIndex = itemsLastIndex + 1;
    if (scrollState == OnScrollListener.SCROLL_STATE_IDLE && mLastItemIndex == itemsLastIndex) {  //自动加载,
        if (mOnFooterRefreshListener != null
                && loadingMoreState == DListViewLoadingMore.LV_NORMAL) {
            updateLoadMoreViewState(DListViewLoadingMore.LV_LOADING);
            mOnFooterRefreshListener.onLoadMore();
        }
    }
}

@Override
public void onScroll(AbsListView view, int firstVisibleItem,
                     int visibleItemCount, int totalItemCount) {
    mFirstItemIndex = firstVisibleItem;
    mLastItemIndex = firstVisibleItem + visibleItemCount - 1;
}

/**
 * 点击事件
 */
@Override
public void onClick(View v) {
    // 防止重复点击
    if (mOnFooterRefreshListener != null
            && loadingMoreState == DListViewLoadingMore.LV_NORMAL) {
        updateLoadMoreViewState(DListViewLoadingMore.LV_LOADING);
        mOnFooterRefreshListener.onLoadMore();
    }

}

/**
 *  注入刷新接口
 * @param onRefreshLoadingMoreListener
 */
/*public void setOnRefreshListener(
        OnRefreshLoadingMoreListener onRefreshLoadingMoreListener) {
    this.onRefreshLoadingMoreListener = onRefreshLoadingMoreListener;
}*/

/*public interface OnRefreshLoadingMoreListener {

    void onRefresh();


    void onLoadMore();
}*/


/**
 * set headerRefreshListener
 *
 * @param headerRefreshListener
 */
public void setOnHeaderRefreshListener(
        OnHeaderRefreshListener headerRefreshListener) {
    String time = "";
    initHeadView(getContext(), time);

    mOnHeaderRefreshListener = headerRefreshListener;

}

/**
 * set headerRefreshListener
 *
 * @param footerRefreshListener
 */
public void setOnFooterRefreshListener(
        OnFooterRefreshListener footerRefreshListener) {
    mOnFooterRefreshListener = footerRefreshListener;

    initLoadMoreView(getContext());
}

/**
 * Interface
 */
public interface OnFooterRefreshListener {
    public void onLoadMore();
}

/**
 * Interface
 */
public interface OnHeaderRefreshListener {
    public void onRefresh();
}

public void addEmptyView(CharSequence charSequence) {
    /*if (mEmptyView.getParent() != null) {
        throw new IllegalStateException("The specified child already has a parent. " +
                "You must call removeView() on the child's parent first.");
    }*/
    mEmptyView.setVisibility(View.GONE);
    mEmptyText.setText(charSequence);
    ViewGroup parent = (ViewGroup) this.getParent();
    if (parent != null)
        ((ViewGroup) this.getParent()).addView(mEmptyView);

    this.setEmptyView(mEmptyView);
}

/**
 * init empty view
 *
 * @param context
 */
private void initEmptyView(Context context) {
    // LayoutInflater inflate = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    mEmptyView = LayoutInflater.from(context).inflate(R.layout.activity_pull_empty, null);

    assert mEmptyView != null;
    mEmptyText = (TextView) mEmptyView.findViewById(R.id.emptyText);
}

@Override
protected void dispatchDraw(Canvas canvas) {
    try {
        super.dispatchDraw(canvas);
    } catch (IndexOutOfBoundsException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

/**
 * show headerline
 *
 * @param isShow
 */
public void setShowHeaderLine(boolean isShow) {
    try {
        if (mHeadHorLineView != null) {
            if (isShow) {
                mHeadHorLineView.setVisibility(VISIBLE);
            } else {
                mHeadHorLineView.setVisibility(GONE);
            }
        }
    } catch (NullPointerException e) {
        e.printStackTrace();
    }
}

public boolean isCick() {
    return isclick;
}

}

下面是xml文件foot

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值