package com.example.listviewdemo;
import com.example.listviewdemo.R;
import android.content.Context;
import android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
public class RefreshListView extends ListView implements AbsListView.OnScrollListener{
private static final int REFRESH_DONE=0;
private static final int PULL_TO_REFRESH=1;
private static final int RELEASH_TO_REFRESH=2;
private static final int REFRESHING=3;
private static final float REFRESH_RATIO=3.0f;
private LinearLayout headerView;
private int headerViewHeight;
private int refreshstate;
private boolean isScrollFirst;
private TextView tv_refresh;
private float startY,offsetY;
private OnRefreshListener mOnRefreshListener;
public RefreshListView(Context context) {
super(context);
init(context);
}
public RefreshListView(Context context,AttributeSet attrs) {
super(context,attrs);
init(context);
}
public RefreshListView(Context context, AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
/**
* 初始化view
* @param context
*/
private void init(Context context){
setOverScrollMode(View.OVER_SCROLL_NEVER);
setOnScrollListener(this);
headerView = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.listview_head_view, null,false);
tv_refresh = (TextView) headerView.findViewById(R.id.tv_refresh);
measureView(headerView);
addHeaderView(headerView);
headerViewHeight = headerView.getMeasuredHeight();
headerView.setPadding(0, -headerViewHeight, 0, 0);
refreshstate = REFRESH_DONE;
}
public void onScrollStateChanged(AbsListView absListView,int i){
}
public void onScroll(AbsListView absListView,int firstVisibleItem,int visibleItemCount,int totalItemCount){
if(firstVisibleItem==0){
isScrollFirst=true;
}else{
isScrollFirst=false;
}
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
startY=ev.getY();
break;
case MotionEvent.ACTION_MOVE:
offsetY=ev.getY()-startY;
if(offsetY > 0 && isScrollFirst && refreshstate!=REFRESHING){
float headerViewShowHeight = offsetY/REFRESH_RATIO;
switch (refreshstate) {
case REFRESH_DONE:
refreshstate=PULL_TO_REFRESH;
break;
case PULL_TO_REFRESH:
setSelection(0);
if(headerViewShowHeight-headerViewShowHeight>=0){
refreshstate = RELEASH_TO_REFRESH;
changeHeaderByState(refreshstate);
}
break;
case RELEASH_TO_REFRESH:
setSelection(0);
if (headerViewShowHeight - headerViewHeight < 0) {
refreshstate = PULL_TO_REFRESH;
changeHeaderByState(refreshstate);
}
break;
}
if(refreshstate == PULL_TO_REFRESH || refreshstate == RELEASH_TO_REFRESH){
headerView.setPadding(0, (int) (headerViewShowHeight-headerViewHeight), 0, 0);
}
}
break;
case MotionEvent.ACTION_UP:
if (refreshstate == PULL_TO_REFRESH) {
refreshstate = REFRESH_DONE;
changeHeaderByState(refreshstate);
}
if (refreshstate == RELEASH_TO_REFRESH) {
refreshstate = REFRESHING;
changeHeaderByState(refreshstate);
mOnRefreshListener.onRefresh();
}
break;
}
return super.onTouchEvent(ev);
}
/**
* 改变headview状态
* @param state
*/
private void changeHeaderByState(int state){
switch (state) {
case REFRESH_DONE:
headerView.setPadding(0, -headerViewHeight, 0, 0);
tv_refresh.setText("下拉刷新");
break;
case RELEASH_TO_REFRESH:
tv_refresh.setText("下拉刷新");
break;
case PULL_TO_REFRESH:
tv_refresh.setText("下拉刷新");
break;
case REFRESHING:
headerView.setPadding(0, 0, 0, 0);
tv_refresh.setText("正在刷新");
break;
default:
break;
}
}
/**
* 下拉刷新监听
*/
public interface OnRefreshListener{
void onRefresh();
}
/**
* 设置下拉刷新
* @param onRefreshListener
*/
public void setOnRefreshListener(OnRefreshListener onRefreshListener){
mOnRefreshListener=onRefreshListener;
}
/**
*下拉刷新完成
*/
public void setOnRefreshComplete(){
refreshstate=REFRESH_DONE;
changeHeaderByState(refreshstate);
}
/**
* 计算空间的高度
* @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 childHeightspc;
if (lpHeight>0){
childHeightspc = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
}else{
childHeightspc = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
}
child.measure( childWidthSpec, childHeightspc);
}
}
package com.example.listviewdemo;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Toast;
public class MainActivity extends Activity implements RefreshListView.OnRefreshListener {
private RefreshListView mListView;
private List<String> mDatas;
private ArrayAdapter<String> mAdapter;
private final static int REFRESH_COMOLETE=0;
private Handler mHandler = new Handler(){
public void handleMessage(Message msg){
switch (msg.what) {
case REFRESH_COMOLETE:
mListView.setOnRefreshComplete();
mAdapter.notifyDataSetChanged();
mListView.setSelection(0);
break;
}
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView(){
mListView = (RefreshListView) findViewById(R.id.listview);
String[] data = new String[]{"下拉刷新","下拉刷新","下拉刷新",
"下拉刷新","下拉刷新","下拉刷新","下拉刷新","下拉刷新"
,"下拉刷新","下拉刷新","下拉刷新","下拉刷新"};
mDatas = new ArrayList<>(Arrays.asList(data));
mAdapter = new ArrayAdapter<>(MainActivity.this, android.R.layout.simple_list_item_1, mDatas);
mListView.setAdapter(mAdapter);
mListView.setOnRefreshListener(this);
mListView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(MainActivity.this, "position=" + position, Toast.LENGTH_SHORT).show();
}
});
}
public void onRefresh(){
new Thread(){
public void run(){
try {
Thread.sleep(3000);
mDatas.add(0,"new下拉刷新");
mHandler.sendEmptyMessage(REFRESH_COMOLETE);
} catch (Exception e) {
}
}
}.start();
}
}