android 安卓自定义listview实现下拉刷新
【1】、重写listView
publicclassMyListViewextendsListViewimplementsOnScrollListener{privatefinalstaticintRELEASE_To_REFRESH=0;//下拉过程的状态值privatefinalstaticintPULL_To_REFRESH=1;//从下拉返回到不刷新的状态值privatefinalstaticintREFRESHING=2;//正在刷新的状态值privatefinalstaticintDONE=3;privatefinalstaticintLOADING=4;//实际的padding的距离与界面上偏移距离的比例privatefinalstaticintRATIO=3;privateLayoutInflaterinflater;//ListView头部下拉刷新的布局privateLinearLayoutheaderView;privateTextViewlvHeaderTipsTv;privateTextViewlvHeaderLastUpdatedTv;privateImageViewlvHeaderArrowIv;privateProgressBarlvHeaderProgressBar;//定义头部下拉刷新的布局的高度privateintheaderContentHeight;privateRotateAnimationanimation;privateRotateAnimationreverseAnimation;privateintstartY;privateintstate;privatebooleanisBack;//用于保证startY的值在一个完整的touch事件中只被记录一次privatebooleanisRecored;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);headerView=(LinearLayout)inflater.inflate(R.layout.lv_header,null);lvHeaderTipsTv=(TextView)headerView.findViewById(R.id.lvHeaderTipsTv);lvHeaderLastUpdatedTv=(TextView)headerView.findViewById(R.id.lvHeaderLastUpdatedTv);lvHeaderArrowIv=(ImageView)headerView.findViewById(R.id.lvHeaderArrowIv);//设置下拉刷新图标的最小高度和宽度lvHeaderArrowIv.setMinimumWidth(70);lvHeaderArrowIv.setMinimumHeight(50);lvHeaderProgressBar=(ProgressBar)headerView.findViewById(R.id.lvHeaderProgressBar);measureView(headerView);headerContentHeight=headerView.getMeasuredHeight();//设置内边距,正好距离顶部为一个负的整个布局的高度,正好把头部隐藏headerView.setPadding(0,-1*headerContentHeight,0,0);//重绘一下headerView.invalidate();//将下拉刷新的布局加入ListView的顶部addHeaderView(headerView,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);//一开始的状态就是下拉刷新完的状态,所以为DONEstate=DONE;//是否正在刷新isRefreshable=false;}@OverridepublicvoidonScrollStateChanged(AbsListViewview,intscrollState){}@OverridepublicvoidonScroll(AbsListViewview,intfirstVisibleItem,intvisibleItemCount,inttotalItemCount){if(firstVisibleItem==0){isRefreshable=true;}else{isRefreshable=false;}}@OverridepublicbooleanonTouchEvent(MotionEventev){if(isRefreshable){switch(ev.getAction()){caseMotionEvent.ACTION_DOWN:if(!isRecored){isRecored=true;startY=(int)ev.getY();//手指按下时记录当前位置}break;caseMotionEvent.ACTION_UP:if(state!=REFRESHING&&state!=LOADING){if(state==PULL_To_REFRESH){state=DONE;changeHeaderViewByState();}if(state==RELEASE_To_REFRESH){state=REFRESHING;changeHeaderViewByState();onLvRefresh();}}isRecored=false;isBack=false;break;caseMotionEvent.ACTION_MOVE:inttempY=(int)ev.getY();if(!isRecored){isRecored=true;startY=tempY;}if(state!=REFRESHING&&isRecored&&state!=LOADING){//保证在设置padding的过程中,当前的位置一直是在head,否则如果当列表超出屏幕的话,当在上推的时候,列表会同时进行滚动//可以松手去刷新了if(state==RELEASE_To_REFRESH){setSelection(0);//往上推了,推到了屏幕足够掩盖head的程度,但是还没有推到全部掩盖的地步if(((tempY-startY)/RATIO<headerContentHeight)//由松开刷新状态转变到下拉刷新状态&&(tempY-startY)>0){state=PULL_To_REFRESH;changeHeaderViewByState();}//一下子推到顶了elseif(tempY-startY<=0){//由松开刷新状态转变到done状态state=DONE;changeHeaderViewByState();}}//还没有到达显示松开刷新的时候,DONE或者是PULL_To_REFRESH状态if(state==PULL_To_REFRESH){setSelection(0);//下拉到可以进入RELEASE_TO_REFRESH的状态if((tempY-startY)/RATIO>=headerContentHeight){//由done或者下拉刷新状态转变到松开刷新state=RELEASE_To_REFRESH;isBack=true;changeHeaderViewByState();}//上推到顶了elseif(tempY-startY<=0){//由DOne或者下拉刷新状态转变到done状态state=DONE;changeHeaderViewByState();}}//done状态下if(state==DONE){if(tempY-startY>0){state=PULL_To_REFRESH;changeHeaderViewByState();}}//更新headView的sizeif(state==PULL_To_REFRESH){headerView.setPadding(0,-1*headerContentHeight+(tempY-startY)/RATIO,0,0);}//更新headView的paddingTopif(state==RELEASE_To_REFRESH){headerView.setPadding(0,(tempY-startY)/RATIO-headerContentHeight,0,0);}}break;default:break;}}returnsuper.onTouchEvent(ev);}//当状态改变时候,调用该方法,以更新界面privatevoidchangeHeaderViewByState(){switch(state){caseRELEASE_To_REFRESH:lvHeaderArrowIv.setVisibility(View.VISIBLE);lvHeaderProgressBar.setVisibility(View.GONE);lvHeaderTipsTv.setVisibility(View.VISIBLE);lvHeaderLastUpdatedTv.setVisibility(View.VISIBLE);lvHeaderArrowIv.clearAnimation();//清除动画lvHeaderArrowIv.startAnimation(animation);//开始动画效果lvHeaderTipsTv.setText("松开刷新");break;casePULL_To_REFRESH:lvHeaderProgressBar.setVisibility(View.GONE);lvHeaderTipsTv.setVisibility(View.VISIBLE);lvHeaderLastUpdatedTv.setVisibility(View.VISIBLE);lvHeaderArrowIv.clearAnimation();lvHeaderArrowIv.setVisibility(View.VISIBLE);//是由RELEASE_To_REFRESH状态转变来的if(isBack){isBack=false;lvHeaderArrowIv.clearAnimation();lvHeaderArrowIv.startAnimation(reverseAnimation);lvHeaderTipsTv.setText("下拉刷新");}else{lvHeaderTipsTv.setText("下拉刷新");}break;caseREFRESHING:headerView.setPadding(0,0,0,0);lvHeaderProgressBar.setVisibility(View.VISIBLE);lvHeaderArrowIv.clearAnimation();lvHeaderArrowIv.setVisibility(View.GONE);lvHeaderTipsTv.setText("正在刷新...");lvHeaderLastUpdatedTv.setVisibility(View.VISIBLE);break;caseDONE:headerView.setPadding(0,-1*headerContentHeight,0,0);lvHeaderProgressBar.setVisibility(View.GONE);lvHeaderArrowIv.clearAnimation();lvHeaderArrowIv.setImageResource(R.drawable.arrow);lvHeaderTipsTv.setText("下拉刷新");lvHeaderLastUpdatedTv.setVisibility(View.VISIBLE);break;}}//此方法直接照搬自网络上的一个下拉刷新的demo,此处是“估计”headView的width以及heightprivatevoidmeasureView(Viewchild){ViewGroup.LayoutParamsparams=child.getLayoutParams();if(params==null){params=newViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT);}intchildWidthSpec=ViewGroup.getChildMeasureSpec(0,0+0,params.width);intlpHeight=params.height;intchildHeightSpec;if(lpHeight>0){childHeightSpec=MeasureSpec.makeMeasureSpec(lpHeight,MeasureSpec.EXACTLY);}else{childHeightSpec=MeasureSpec.makeMeasureSpec(0,MeasureSpec.UNSPECIFIED);}child.measure(childWidthSpec,childHeightSpec);}publicvoidsetonRefreshListener(OnRefreshListenerrefreshListener){this.refreshListener=refreshListener;isRefreshable=true;}publicinterfaceOnRefreshListener{publicvoidonRefresh();}publicvoidonRefreshComplete(){state=DONE;lvHeaderLastUpdatedTv.setText("最近更新:"+newDate().toLocaleString());changeHeaderViewByState();}privatevoidonLvRefresh(){if(refreshListener!=null){refreshListener.onRefresh();}}publicvoidsetAdapter(BaseAdapteradapter){lvHeaderLastUpdatedTv.setText("最近更新:"+newDate().toLocaleString());super.setAdapter(adapter);}}
【2】刷新头部xml文件lv_header.xml
<?xmlversion="1.0"encoding="utf-8"?><!--ListView的头部--><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="fill_parent"android:layout_height="wrap_content"android:background="#000000"><!--内容--><RelativeLayoutandroid:id="@+id/head_contentLayout"android:layout_width="fill_parent"android:layout_height="wrap_content"android:paddingLeft="30dp"><!--箭头图像、进度条--><FrameLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentLeft="true"android:layout_centerVertical="true"><!--箭头--><ImageViewandroid:id="@+id/lvHeaderArrowIv"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:src="@drawable/arrow"/><!--进度条--><ProgressBarandroid:id="@+id/lvHeaderProgressBar"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:visibility="gone"/></FrameLayout><!--提示、最近更新--><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerHorizontal="true"android:gravity="center_horizontal"android:orientation="vertical"><!--提示--><TextViewandroid:id="@+id/lvHeaderTipsTv"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="下拉刷新"android:textColor="@color/white"android:textSize="20sp"/><!--最近更新--><TextViewandroid:id="@+id/lvHeaderLastUpdatedTv"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="上次更新"android:textColor="@color/gold"android:textSize="10sp"/></LinearLayout></RelativeLayout></LinearLayout>
【3】调用方法
adapter=newLvAdapter(list,this);lv.setAdapter(adapter);lv.setonRefreshListener(newOnRefreshListener(){@OverridepublicvoidonRefresh(){newAsyncTask<Void,Void,Void>(){protectedVoiddoInBackground(Void...params){try{Thread.sleep(1000);}catch(Exceptione){e.printStackTrace();}list.add("刷新后添加的内容");returnnull;}@OverrideprotectedvoidonPostExecute(Voidresult){adapter.notifyDataSetChanged();lv.onRefreshComplete();}}.execute(null,null,null);}});}
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。