您的位置:首页 > 移动开发 > Android开发

Android中实现List下拉刷新

2015-07-16 14:27 567 查看
今天,我以如何在Android中实现下拉刷新介绍下主要实现步骤:

1.重写ListView。ListView中有一个addHeaderView()的方法用来在顶部添加一个view。

2.让ListView实现触摸事件和滚动事件,来根据状态动态改变view。

3.利用回调接口来更新ListView。

下面看具体代码:

public class RefreshListView extends ListView implements OnScrollListener{

private View headerView;

private int headerViewHeight;

private int firstVisibleItem;//当前第一个可见的Item的位置

private boolean mark;//标记:当前是否在ListView的最顶端按下的

private int startY;//按下时的Y值

private int state;//当前的状态

private final int NONE = 0;//正常状态

private final int PULL = 1;//提示下拉状态

private final int RELESE = 2;//松开释放的状态

private final int REFLASHING = 3;//正在刷新的状态

private int scrollState;//当前滚动状态

private RefreshInterface refreshInterface;

public RefreshListView(Context context) {

super(context);

initView(context);

}



public RefreshListView(Context context, AttributeSet attrs) {

super(context, attrs);

initView(context);

}

public RefreshListView(Context context, AttributeSet attrs,int defStyle) {

// TODO Auto-generated constructor stub

super(context,attrs,defStyle);

initView(context);

}



/**

* 初始化组件 添加顶部布局文件到ListView

* @param context

*/

private void initView(Context context){

headerView = LayoutInflater.from(context).inflate(R.layout.header_listview, null);

measureView(headerView);

headerViewHeight = headerView.getMeasuredHeight();//此处需要通知父布局headerView占的宽高。

topPadding(-headerViewHeight);

this.addHeaderView(headerView);

this.setOnScrollListener(this);

}

/**

* 通知父布局view所占的宽高

* @param view

*/

private void measureView(View view){

ViewGroup.LayoutParams layoutParams = view.getLayoutParams();

if(layoutParams == null){

layoutParams = new ViewGroup.LayoutParams(

ViewGroup.LayoutParams.MATCH_PARENT,

ViewGroup.LayoutParams.MATCH_PARENT);



}

//获取宽高

int width = ViewGroup.getChildMeasureSpec(0, 0,layoutParams.width);

int height;

int tempHeight = layoutParams.height;

if(tempHeight > 0){

height = MeasureSpec.makeMeasureSpec(tempHeight, MeasureSpec.EXACTLY);

}else{

height = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);

}

//填充View

view.measure(width, height);

}

/**

* 设置headerView的上边距

* @param topPadding

*/

private void topPadding(int topPadding){

headerView.setPadding(headerView.getPaddingLeft(),

topPadding ,

headerView.getPaddingRight(),

headerView.getPaddingBottom());

headerView.invalidate();

}




@Override

public void onScrollStateChanged(AbsListView view, int scrollState) {

// TODO Auto-generated method stub

this.scrollState = scrollState;

}


@Override

public void onScroll(AbsListView view, int firstVisibleItem,

int visibleItemCount, int totalItemCount) {

this.firstVisibleItem = firstVisibleItem;

}

@Override

public boolean onTouchEvent(MotionEvent event) {

switch (event.getAction()) {

//按下

case MotionEvent.ACTION_DOWN:

if(firstVisibleItem == 0){

//第一项Item在最顶端

mark = true;

startY = (int)event.getY();

}

break;

//弹起

case MotionEvent.ACTION_UP:

if(state == RELESE){

state = REFLASHING;

//加载最新数据

reflashView();

refreshInterface.onRefresh();

}else if(state == PULL){

state = NONE;

mark = false;

reflashView();

}

break;

//移动

case MotionEvent.ACTION_MOVE:

move(event);

break;

default:

break;

}

return super.onTouchEvent(event);

}

private void move(MotionEvent event){

if(!mark){

return;

}

int currentY = (int)event.getY();

int space = currentY - startY;

int topPadding = space - headerViewHeight;

switch (state) {

case NONE:

if(space > 0){

state = PULL;

reflashView();

}

break;

case PULL:

topPadding(topPadding);

if(space > headerViewHeight + 30 && scrollState == SCROLL_STATE_TOUCH_SCROLL){

state = RELESE;

reflashView();

}

break;

case RELESE:

topPadding(topPadding);

if(space < headerViewHeight + 30 ){

state = PULL;

reflashView();

}else if(space <= 0){

state = NONE;

mark = false;

reflashView();

}

break;

default:

break;

}

}

//根据状态更新显示

private void reflashView(){

TextView textView = (TextView)findViewById(R.id.tip);

ImageView arrow = (ImageView)findViewById(R.id.refresh_arrow);

ProgressBar progress = (ProgressBar)findViewById(R.id.progress);

RotateAnimation animationDown = new RotateAnimation(

0,

180,

RotateAnimation.RELATIVE_TO_SELF,

0.5f,

RotateAnimation.RELATIVE_TO_SELF,

0.5f);

RotateAnimation animationUp = new RotateAnimation(

180,

0,

RotateAnimation.RELATIVE_TO_SELF,

0.5f,

RotateAnimation.RELATIVE_TO_SELF,

0.5f);

animationDown.setDuration(500);

animationDown.setFillAfter(true);

animationUp.setDuration(500);

animationUp.setFillAfter(true);

switch (state) {

case NONE:

topPadding(-headerViewHeight);

arrow.clearAnimation();

break;

case PULL:

arrow.setVisibility(View.VISIBLE);

progress.setVisibility(View.GONE);

textView.setText("下拉可以刷新");

arrow.clearAnimation();

arrow.setAnimation(animationUp);



break;

case RELESE:

arrow.setVisibility(View.VISIBLE);

progress.setVisibility(View.GONE);

textView.setText("松开可以刷新");

arrow.clearAnimation();

arrow.setAnimation(animationDown);

break;

case REFLASHING:

topPadding(50);

arrow.setVisibility(View.GONE);

progress.setVisibility(View.VISIBLE);

textView.setText("正在刷新");

arrow.clearAnimation();

break;

default:

break;

}

}

/**

* 刷新完成

*/

public void refreshComplete(){

state = NONE;

mark = false;

TextView lastupdatetime = (TextView)findViewById(R.id.lastupdatetime);

SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

Date date = new Date(System.currentTimeMillis());

String time = format.format(date);

lastupdatetime.setText(time);

reflashView();

}

/**

* 刷新数据接口

*/

public interface RefreshInterface{

public void onRefresh();

}

public void setInterface(RefreshInterface refreshInterface){

this.refreshInterface = refreshInterface;

}


}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: