android listView下拉刷新.docx
《android listView下拉刷新.docx》由会员分享,可在线阅读,更多相关《android listView下拉刷新.docx(21页珍藏版)》请在冰豆网上搜索。
androidlistView下拉刷新
AndroidlistView下拉刷新
1.自定义的listView
package.karl.list;
importjava.text.SimpleDateFormat;
importjava.util.Date;
importandroid.content.Context;
importandroid.util.AttributeSet;
importandroid.util.Log;
importandroid.view.LayoutInflater;
importandroid.view.MotionEvent;
importandroid.view.View;
importandroid.view.ViewGroup;
importandroid.view.animation.LinearInterpolator;
importandroid.view.animation.RotateAnimation;
importandroid.widget.AbsListView;
importandroid.widget.BaseAdapter;
importandroid.widget.ImageView;
importandroid.widget.LinearLayout;
importandroid.widget.ListView;
importandroid.widget.AbsListView.OnScrollListener;
importandroid.widget.ProgressBar;
importandroid.widget.TextView;
publicclassMyListViewextendsListViewimplementsOnScrollListener
{
privatestaticfinalStringTAG="listview";
privatefinalstaticintRELEASE_To_REFRESH=0;
privatefinalstaticintPULL_To_REFRESH=1;
privatefinalstaticintREFRESHING=2;
privatefinalstaticintDONE=3;
privatefinalstaticintLOADING=4;
//实际的padding的距离与界面上偏移距离的比例
privatefinalstaticintRATIO=3;
privateLayoutInflaterinflater;
privateLinearLayoutheadView;
privateTextViewtipsTextview;
privateTextViewlastUpdatedTextView;
privateImageViewarrowImageView;
privateProgressBarprogressBar;
privateRotateAnimationanimation;
privateRotateAnimationreverseAnimation;
//用于保证startY的值在一个完整的touch事件中只被记录一次
privatebooleanisRecored;
privateintheadContentWidth;
privateintheadContentHeight;
privateintstartY;
privateintfirstItemIndex;
privateintstate;
privatebooleanisBack;
privateOnRefreshListenerrefreshListener;
privatebooleanisRefreshable;
publicMyListView(Contextcontext)
{
super(context);
init(context);
}
//?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
publicMyListView(Contextcontext,AttributeSetattrs)
{
super(context,attrs);
init(context);
}
privatevoidinit(Contextcontext)
{
//setCacheColorHint(context.getResources().getColor(R.color.transparent));
inflater=LayoutInflater.from(context);
headView=(LinearLayout)inflater.inflate(R.layout.head,null);
arrowImageView=(ImageView)headView
.findViewById(R.id.head_arrowImageView);
arrowImageView.setMinimumWidth(70);
arrowImageView.setMinimumHeight(50);
progressBar=(ProgressBar)headView.findViewById(R.id.head_progressBar);
tipsTextview=(TextView)headView.findViewById(R.id.head_tipsTextView);
lastUpdatedTextView=(TextView)headView
.findViewById(R.id.head_lastUpdatedTextView);
measureView(headView);
headContentHeight=headView.getMeasuredHeight();
headContentWidth=headView.getMeasuredWidth();
headView.setPadding(0,-1*headContentHeight,0,0);
headView.invalidate();
Log.v("size","width:
"+headContentWidth+"height:
"+headContentHeight);
addHeaderView(headView,null,false);
setOnScrollListener(this);
animation=newRotateAnimation(0,-180,RotateAnimation.RELATIVE_TO_SELF,
0.5f,RotateAnimation.RELATIVE_TO_SELF,0.5f);
animation.setInterpolator(newLinearInterpolator());
animation.setDuration(250);
animation.setFillAfter(true);
reverseAnimation=newRotateAnimation(-180,0,
RotateAnimation.RELATIVE_TO_SELF,0.5f,
RotateAnimation.RELATIVE_TO_SELF,0.5f);
reverseAnimation.setInterpolator(newLinearInterpolator());
reverseAnimation.setDuration(200);
reverseAnimation.setFillAfter(true);
state=DONE;
isRefreshable=false;
}
publicvoidonScroll(AbsListViewarg0,intfirstVisiableItem,intarg2,
intarg3)
{
firstItemIndex=firstVisiableItem;
}
publicvoidonScrollStateChanged(AbsListViewarg0,intarg1)
{
}
publicbooleanonTouchEvent(MotionEventevent)
{
if(isRefreshable)
{
switch(event.getAction())
{
caseMotionEvent.ACTION_DOWN:
if(firstItemIndex==0&&!
isRecored)
{
isRecored=true;
startY=(int)event.getY();
Log.v(TAG,"在down时候记录当前位置‘");
}
break;
caseMotionEvent.ACTION_UP:
if(state!
=REFRESHING&&state!
=LOADING)
{
if(state==DONE)
{
//什么都不做
}
if(state==PULL_To_REFRESH)
{
state=DONE;
changeHeaderViewByState();
Log.v(TAG,"由下拉刷新状态,到done状态");
}
if(state==RELEASE_To_REFRESH)
{
state=REFRESHING;
changeHeaderViewByState();
onRefresh();
Log.v(TAG,"由松开刷新状态,到done状态");
}
}
isRecored=false;
isBack=false;
break;
caseMotionEvent.ACTION_MOVE:
inttempY=(int)event.getY();
if(!
isRecored&&firstItemIndex==0)
{
Log.v(TAG,"在move时候记录下位置");
isRecored=true;
startY=tempY;
}
if(state!
=REFRESHING&&isRecored&&state!
=LOADING)
{
//保证在设置padding的过程中,当前的位置一直是在head,否则如果当列表超出屏幕的话,当在上推的时候,列表会同时进行滚动
//可以松手去刷新了
if(state==RELEASE_To_REFRESH)
{
setSelection(0);
//往上推了,推到了屏幕足够掩盖head的程度,但是还没有推到全部掩盖的地步
if(((tempY-startY)/RATIO&&(tempY-startY)>0)
{
state=PULL_To_REFRESH;
changeHeaderViewByState();
Log.v(TAG,"由松开刷新状态转变到下拉刷新状态");
}
//一下子推到顶了
else
if(tempY-startY<=0)
{
state=DONE;
changeHeaderViewByState();
Log.v(TAG,"由松开刷新状态转变到done状态");
}
//往下拉了,或者还没有上推到屏幕顶部掩盖head的地步
else
{
//不用进行特别的操作,只用更新paddingTop的值就行了
}
}
//还没有到达显示松开刷新的时候,DONE或者是PULL_To_REFRESH状态
if(state==PULL_To_REFRESH)
{
setSelection(0);
//下拉到可以进入RELEASE_TO_REFRESH的状态
if((tempY-startY)/RATIO>=headContentHeight)
{
state=RELEASE_To_REFRESH;
isBack=true;
changeHeaderViewByState();
Log.v(TAG,"由done或者下拉刷新状态转变到松开刷新");
}
//上推到顶了
else
if(tempY-startY<=0)
{
state=DONE;
changeHeaderViewByState();
Log.v(TAG,"由DOne或者下拉刷新状态转变到done状态");
}
}
//done状态下
if(state==DONE)
{
if(tempY-startY>0)
{
state=PULL_To_REFRESH;
changeHeaderViewByState();
}
}
//更新headView的size
if(state==PULL_To_REFRESH)
{
headView.setPadding(0,-1*headContentHeight
+(tempY-startY)/RATIO,0,0);
}
//更新headView的paddingTop
if(state==RELEASE_To_REFRESH)
{
headView.setPadding(0,(tempY-startY)/RATIO
-headContentHeight,0,0);
}
}
break;
}
}
returnsuper.onTouchEvent(event);
}
//当状态改变时候,调用该方法,以更新界面
privatevoidchangeHeaderViewByState()
{
switch(state)
{
caseRELEASE_To_REFRESH:
arrowImageView.setVisibility(View.VISIBLE);
progressBar.setVisibility(View.GONE);
tipsTextview.setVisibility(View.VISIBLE);
lastUpdatedTextView.setVisibility(View.VISIBLE);
arrowImageView.clearAnimation();
arrowImageView.startAnimation(animation);
tipsTextview.setText("松开刷新");
Log.v(TAG,"当前状态,松开刷新");
break;
casePULL_To_REFRESH:
progressBar.setVisibility(View.GONE);
tipsTextview.setVisibility(View.VISIBLE);
lastUpdatedTextView.setVisibility(View.VISIBLE);
arrowImageView.clearAnimation();
arrowImageView.setVisibility(View.VISIBLE);
//是由RELEASE_To_REFRESH状态转变来的
if(isBack)
{
isBack=false;
arrowImageView.clearAnimation();
arrowImageView.startAnimation(reverseAnimation);
tipsTextview.setText("下拉刷新");
}
else
{
tipsTextview.setText("下拉刷新");
}
Log.v(TAG,"当前状态,下拉刷新");
break;
caseREFRESHING:
headView.setPadding(0,0,0,0);
progressBar.setVisibility(View.VISIBLE);
arrowImageView.clearAnimation();
arrowImageView.setVisibility(View.GONE);
tipsTextview.setText("正在刷新...");
lastUpdatedTextView.setVisibility(View.VISIBLE);
Log.v(TAG,"当前状态,正在刷新...");
break;
caseDONE:
headView.setPadding(0,-1*headContentHeight,0,0);
progressBar.setVisibility(View.GONE);
arrowImageView.clearAnimation();
arrowImageView.setImageResource(R.drawable.arrow_down);
tipsTextview.setText("下拉刷新");
lastUpdatedTextView.setVisibility(View.VISIBLE);
Log.v(TAG,"当前状态,done");
break;
}
}
publicvoidsetonRefreshListener(OnRefreshListenerrefreshListener)
{
this.refreshListener=refreshListener;
isRefreshable=true;
}
publicinterfaceOnRefreshListener
{
publicvoidonRefresh();
}
publicvoidonRefreshComplete()
{
state=DONE;
SimpleDateFormatformat=newSimpleDateFormat("yyyy年MM月dd日HH:
mm");
Stringdate=format.format(newDate());
lastUpdatedTextView.setText("最近更新:
"+date);
changeHeaderViewByState();
}
privatevoidonRefresh()
{
if(refreshListener!
=null)
{
refreshListener.onRefresh();
}
}
//此方法直接照搬自网络上的一个下拉刷新的demo,此处是“估计”headView的width以及height
privatevoidmeasureView(Viewchild)
{
ViewGroup.LayoutParamsp=child.getLayoutParams();
if(p==null)
{
p=newViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
}
intchildWidthSpec=ViewGroup.getChildMeasureSpec(0,0+0,p.width);
intlpHeight=p.height;
intchildHeightSpec;
if(lpHeight>0)
{
childHeightSpec=MeasureSpec.makeMeasureSpec(lpHeight,
MeasureSpec.EXACTLY);
}
else
{
childHeightSpec=MeasureSpec.makeMeasureSpec(0,
MeasureSpec.UNSPECIFIED);
}
child.measure(childWidthSpec,childHeightSpec);
}
publicvoidsetAdapter(BaseAdapteradapter)
{
SimpleDateFormatformat=newSimpleDateFormat("yyyy年MM月dd日HH:
mm");
Stringdate=format.format(newDate());
lastUpdatedTextView.setText("最近更新:
"+date);
super.setAdapter(adapter);
}
}
2.Activity实例
package.karl.list;
importjava.