public class RefreshListView extends ListView implements AbsListView.OnScrollListener {
private View headView;
private View footView;
private TextView tv_head_showMsg,tv_foot_showMsg;
private ProgressBar pb_head,pb_foot;
private int headViewHeight;
private int footViewHeight;
private int downY;
private final int pull_refresh = 0;
private final int isRefreshing = 1;
private final int releaseToRefresh = 2;
private int currentStatus = pull_refresh;
private onRefreshListener mRefreshListener;
private boolean isLoadMore = false;
public RefreshListView(Context context) {
this(context, null);
}
public RefreshListView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public RefreshListView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
/**
* 初始化
*/
private void init() {
initHeadView();
initFooterView();
this.setOnScrollListener(this);
}
/**
* 初始化头部布局
*/
private void initHeadView() {
headView = View.inflate(getContext(), R.layout.refreshheadview, null);
tv_head_showMsg = (TextView) headView.findViewById(R.id.tv_showMsg);
pb_head = (ProgressBar) headView.findViewById(R.id.pb_head);
headView.measure(0, 0);
headViewHeight = headView.getMeasuredHeight();
setTopPadding(-headViewHeight);
this.addHeaderView(headView);
}
/**
* 初始化底部布局
*/
private void initFooterView() {
footView = View.inflate(getContext(), R.layout.refreshfootview, null);
tv_foot_showMsg = (TextView) footView.findViewById(R.id.tv_foot_showMsg);
pb_foot = (ProgressBar) footView.findViewById(R.id.pb_foot);
footView.measure(0, 0);
footViewHeight = footView.getMeasuredHeight();
setBottomPadding(-footViewHeight);
this.addFooterView(footView);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
downY = (int) ev.getY();
break;
case MotionEvent.ACTION_MOVE:
if (currentStatus == isRefreshing) {
break;
}
int moveY = (int) (ev.getY() - downY);
int headPadding = moveY - headViewHeight;
if (headPadding > -headViewHeight && getFirstVisiblePosition() == 0) {
setTopPadding(headPadding);
if (headPadding > 0 && currentStatus == pull_refresh) {
currentStatus = releaseToRefresh;
} else if (headPadding < 0 && currentStatus == releaseToRefresh) {
currentStatus = pull_refresh;
}
updateHeadView();
return true;
}
break;
case MotionEvent.ACTION_UP:
if (currentStatus == pull_refresh) {
setTopPadding(-headViewHeight);
} else if (currentStatus == releaseToRefresh) {
setTopPadding(0);
currentStatus = isRefreshing;
updateHeadView();
if (mRefreshListener != null) {
mRefreshListener.onPullRefresh();
}
}
break;
}
return super.onTouchEvent(ev);
}
private void setTopPadding(int topPadding) {
if (headView != null) {
headView.setPadding(0, topPadding, 0, 0);
}
}
private void setBottomPadding(int bottomPadding) {
if (footView != null) {
footView.setPadding(0, bottomPadding, 0, 0);
}
}
/**
* 更新headView状态,
*/
private void updateHeadView() {
switch (currentStatus) {
case pull_refresh:
tv_head_showMsg.setText("下拉刷新");
pb_head.setVisibility(View.GONE);
break;
case releaseToRefresh:
tv_head_showMsg.setText("松开刷新");
break;
case isRefreshing:
tv_head_showMsg.setText("正在刷新...");
pb_head.setVisibility(View.VISIBLE);
break;
}
}
/**
* SCROLL_STATE_IDLE:闲置状态,就是手指松开
* SCROLL_STATE_TOUCH_SCROLL:手指触摸滑动,就是按着来滑动
* SCROLL_STATE_FLING:快速滑动后松开
*/
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (scrollState == SCROLL_STATE_IDLE && getLastVisiblePosition() + 1 == getCount() && !isLoadMore) {
isLoadMore = true;
setBottomPadding(0);
setSelection(getCount());
tv_foot_showMsg.setText("正在刷新...");
pb_foot.setVisibility(View.VISIBLE);
if (mRefreshListener != null) {
mRefreshListener.onLoadMore();
}
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}
/**
* 刷新完成
*/
public void refreshComplete() {
if (isLoadMore) {
setBottomPadding(-footViewHeight);
pb_foot.setVisibility(View.GONE);
isLoadMore = false;
} else {
setTopPadding(-headViewHeight);
tv_head_showMsg.setText("下拉刷新");
pb_head.setVisibility(View.GONE);
currentStatus = pull_refresh;
}
}
/**
* 刷新事件监听
* @param refreshListener
*/
public void setOnRefreshListener(onRefreshListener refreshListener) {
this.mRefreshListener = refreshListener;
}
/**
* 接口回调模式
*/
public interface onRefreshListener {
void onPullRefresh();
void onLoadMore();
}
/**
* 适配器模式
*/
public static class RefreshAdapter implements onRefreshListener {
@Override
public void onPullRefresh() {
}
@Override
public void onLoadMore() {
}
}
}
public class MainActivity extends Activity {
private RefreshListView lv;
private List<String> list;
private myAdapter adapter;
private int addHeadItem = 0;
private int addFootItem = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
list.add("simple");
}
lv = (RefreshListView) findViewById(R.id.lv);
adapter = new myAdapter();
lv.setAdapter(adapter);
lv.setOnRefreshListener(new RefreshListView.onRefreshListener() {
@Override
public void onPullRefresh() {
list.add(0, "pull_refresh" + addHeadItem);
addHeadItem++;
lv.postDelayed(new Runnable() {
@Override
public void run() {
adapter.notifyDataSetChanged();
lv.refreshComplete();
}
}, 3000);
}
@Override
public void onLoadMore() {
lv.postDelayed(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
list.add("onLoadMore" + addFootItem);
addFootItem++;
}
adapter.notifyDataSetChanged();
lv.refreshComplete();
}
}, 3000);
}
});
}
private class myAdapter extends BaseAdapter {
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = View.inflate(MainActivity.this, R.layout.convert_item, null);
holder.tv = (TextView) convertView.findViewById(R.id.tv);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.tv.setText(list.get(position));
return convertView;
}
class ViewHolder {
TextView tv;
}
}
}
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="#00000000">
<ProgressBar
android:id="@+id/pb_head"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:visibility="gone"
/>
<TextView
android:id="@+id/tv_showMsg"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:gravity="center_vertical"
android:text="这是下拉刷新头部"
android:textSize="18sp" />
</RelativeLayout>
</RelativeLayout>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="#66FFFFFF">
<ProgressBar
android:id="@+id/pb_foot"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:visibility="gone" />
<TextView
android:id="@+id/tv_foot_showMsg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="上拉加载更多"
android:textSize="15sp" />
</RelativeLayout>
</RelativeLayout>