自定义listview,支持上拉下拉刷新,自带demo .
这个博客好想不能提供下载代码啊, 我只能把代码贴出来了...
其实你只需看用法, 不用关心具体实现,demo非常容易看懂
publicclassCustomListViewActivityextendsActivity{privateCustomListViewlistview;privateArrayList<String>data;privateBaseAdapteradapter;/**Calledwhentheactivityisfirstcreated.*/@OverridepublicvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);init();setListener();}privatevoidinit(){data=newArrayList<String>();//虚拟一些数据data.add("a");data.add("b");data.add("c");data.add("e");data.add("f");data.add("g");data.add("h");data.add("i");data.add("j");data.add("k");data.add("L");data.add("M");data.add("L");data.add("N");data.add("O");data.add("P");data.add("Q");listview=(CustomListView)findViewById(R.id.listview);adapter=newBaseAdapter(){@OverridepublicintgetCount(){returndata.size();}@OverridepublicObjectgetItem(intposition){returnnull;}@OverridepubliclonggetItemId(intposition){returnposition;}@OverridepublicViewgetView(intposition,ViewconvertView,ViewGroupparent){TextViewtextView=newTextView(getApplicationContext());textView.setHeight(100);textView.setTextSize(20);textView.setGravity(Gravity.CENTER);textView.setBackgroundColor(0x66666666);textView.setTextColor(0xaaffffff);textView.setText(data.get(position));returntextView;}};listview.setAdapter(adapter);}privatevoidsetListener(){listview.setOnRefreshListner(newOnRefreshListner(){@OverridepublicvoidonRefresh(){newAsyncTask<Void,Void,ArrayList<String>>(){@OverrideprotectedArrayList<String>doInBackground(Void...params){try{//模拟从服务器获取数据的过程Thread.sleep(1500);}catch(InterruptedExceptione){e.printStackTrace();}ArrayList<String>virtualData=newArrayList<String>();virtualData.add("Head刷新后的新数据1");virtualData.add("Head刷新后的新数据2");virtualData.add("Head刷新后的新数据3");virtualData.add("Head刷新后的新数据4");virtualData.add("Head刷新后的新数据5");virtualData.add("Head刷新后的新数据6");returnvirtualData;}//更新UI的方法,系统自动实现@OverrideprotectedvoidonPostExecute(ArrayList<String>result){data.addAll(0,result);//注意是往前添加数据adapter.notifyDataSetChanged();listview.onRefreshComplete();//完成下拉刷新,这个方法要调用super.onPostExecute(result);}}.execute();}});//创建FootViewfinalViewfooter=View.inflate(CustomListViewActivity.this,R.layout.footer,null);listview.setOnAddFootListener(newOnAddFootListener(){@OverridepublicvoidaddFoot(){listview.addFooterView(footer);}});listview.setOnFootLoadingListener(newOnFootLoadingListener(){@OverridepublicvoidonFootLoading(){newAsyncTask<Void,Void,ArrayList<String>>(){@OverrideprotectedArrayList<String>doInBackground(Void...params){try{//模拟从服务器获取数据的过程Thread.sleep(2000);}catch(InterruptedExceptione){e.printStackTrace();}ArrayList<String>virtualData=newArrayList<String>();virtualData.add("Foot刷新后的新数据1");virtualData.add("Foot刷新后的新数据2");virtualData.add("Foot刷新后的新数据3");virtualData.add("Foot刷新后的新数据4");virtualData.add("Foot刷新后的新数据5");virtualData.add("Foot刷新后的新数据6");returnvirtualData;}//在doInBackground后面执行@OverrideprotectedvoidonPostExecute(ArrayList<String>result){data.addAll(result);//这个是往后添加数据adapter.notifyDataSetChanged();listview.onFootLoadingComplete();//完成上拉刷新,就是底部加载完毕,这个方法要调用//移除footer,这个动作不能少listview.removeFooterView(footer);super.onPostExecute(result);}}.execute();}});}}
下面上listview的代码,有点长...
/***支持下拉刷新和上拉刷新*可自定义上啦和下拉过程的操作,推荐使用AsyncTask*需自定义Foot的View,然后只需在addFoot方法中添加即可*@authorlxj**/publicclassCustomListViewextendsListViewimplementsOnScrollListener{privatestaticfinalintDONE=0;privatestaticfinalintPULL_TO_REFRESH=1;privatestaticfinalintRELEASE_TO_REFRESH=2;privatestaticfinalintREFRESHING=3;privatestaticfinalfloatRATIO=3;//用来设置实际间距和上边距之间的比例privateintstate;//当前下拉刷新的状态privateintfirstVisibleIndex;//在listview中第一个可以看见的itemprivateViewheadView;privateImageViewheadArrow;privateProgressBarprogressBar;privateTextViewheadTitle;privateTextViewheadLastUpdate;privateintheadContentWidth;privateintheadContentHeight;privateAnimationanimation;privateAnimationreverseAnimation;privateOnRefreshListnerrefreshListner;//刷新监听器privatebooleanisRefreshable;privatebooleanisRecored=false;//用来记录第一次按下坐标点,在整个滑动的过程中只记录一次privatefloatstartY;privatebooleanisBack=false;//是从松开刷新状态来到的下拉刷新状态publicCustomListView(Contextcontext,AttributeSetattrs){super(context,attrs);init(context);}privatevoidinit(Contextcontext){//listview设置滑动时缓冲背景色setCacheColorHint(0x00000000);headView=View.inflate(context,R.layout.head,null);headArrow=(ImageView)headView.findViewById(R.id.head_arrow);progressBar=(ProgressBar)headView.findViewById(R.id.progressbar);headTitle=(TextView)headView.findViewById(R.id.head_title);headLastUpdate=(TextView)headView.findViewById(R.id.head_last_update);headArrow.setMinimumWidth(50);headArrow.setMinimumHeight(70);MeasureView(headView);headContentWidth=headView.getMeasuredWidth();headContentHeight=headView.getMeasuredHeight();headView.setPadding(0,-1*headContentHeight,0,0);//为listView加入顶部ViewaddHeaderView(headView);setOnScrollListener(this);animation=newRotateAnimation(-180,0,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);animation.setDuration(250);animation.setFillAfter(true);//设定动画结束时,停留在动画结束位置(保留动画效果)animation.setInterpolator(newLinearInterpolator());//匀速变化reverseAnimation=newRotateAnimation(0,-180,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);reverseAnimation.setDuration(200);reverseAnimation.setFillAfter(true);//设定动画结束时,停留在动画结束位置(保留动画效果)reverseAnimation.setInterpolator(newLinearInterpolator());//匀速变化//设置当前headView的状态state=DONE;//设置当前下拉刷新是否可用isRefreshable=false;}/***测量headView的宽高**@paramchild*/privatevoidMeasureView(Viewchild){ViewGroup.LayoutParamslp=child.getLayoutParams();if(null==lp){lp=newViewGroup.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT);}intmeasureChildWidth=ViewGroup.getChildMeasureSpec(0,0,lp.width);intmeasureChildHeight;if(lp.height>0){measureChildHeight=MeasureSpec.makeMeasureSpec(lp.height,MeasureSpec.EXACTLY);}else{measureChildHeight=MeasureSpec.makeMeasureSpec(0,MeasureSpec.UNSPECIFIED);}child.measure(measureChildWidth,measureChildHeight);}@OverridepublicbooleanonTouchEvent(MotionEventevent){switch(event.getAction()){caseMotionEvent.ACTION_DOWN:if(firstVisibleIndex==0&&!isRecored){startY=event.getY();isRecored=true;}break;caseMotionEvent.ACTION_MOVE:floattempY=event.getY();if(firstVisibleIndex==0&&!isRecored){startY=tempY;isRecored=true;}if(state!=REFRESHING){if(state==PULL_TO_REFRESH){//向下拉了从下拉刷新的状态来到松开刷新的状态if((tempY-startY)/RATIO>=headContentHeight&&(tempY-startY)>0){state=RELEASE_TO_REFRESH;changeHeadViewOfState();}//向上推了从下拉刷新的状态来到刷新完成的状态elseif((tempY-startY)<=0){state=DONE;changeHeadViewOfState();}}elseif(state==RELEASE_TO_REFRESH){//向上推了还没有完全将HEADVIEW隐藏掉(可以看到一部分)//从松开刷新的状态来到下拉刷新的状态if((tempY-startY)/RATIO<headContentHeight&&(tempY-startY)>0){state=PULL_TO_REFRESH;changeHeadViewOfState();isBack=true;}//向上推了一下子推到了最上面从松开刷新的状态来到刷新完成的状态(数据不刷新的)elseif((tempY-startY)<=0){state=DONE;changeHeadViewOfState();}}elseif(state==DONE){//刷新完成的状态来到下拉刷新的状态if((tempY-startY)>0){state=PULL_TO_REFRESH;changeHeadViewOfState();}}if(state==PULL_TO_REFRESH){headView.setPadding(0,(int)((tempY-startY)/RATIO-headContentHeight),0,0);}if(state==RELEASE_TO_REFRESH){headView.setPadding(0,(int)((tempY-startY)/RATIO-headContentHeight),0,0);}}break;caseMotionEvent.ACTION_UP:if(state!=REFRESHING){if(state==PULL_TO_REFRESH){//松手state=DONE;changeHeadViewOfState();}elseif(state==RELEASE_TO_REFRESH){//松手state=REFRESHING;changeHeadViewOfState();//执行数据刷新方法onRefresh();}}isRecored=false;isBack=false;break;}returnsuper.onTouchEvent(event);}/***执行下拉刷新*/privatevoidonRefresh(){if(refreshListner!=null){refreshListner.onRefresh();}}/***HeadView的状态变化效果*/privatevoidchangeHeadViewOfState(){//switch(state){casePULL_TO_REFRESH:headArrow.setVisibility(View.VISIBLE);progressBar.setVisibility(View.GONE);headTitle.setVisibility(View.VISIBLE);headLastUpdate.setVisibility(View.VISIBLE);headArrow.clearAnimation();headTitle.setText("下拉可以刷新");//由松开刷新到下拉刷新if(isBack){headArrow.startAnimation(animation);isBack=false;}break;caseRELEASE_TO_REFRESH:headArrow.setVisibility(View.VISIBLE);progressBar.setVisibility(View.GONE);headTitle.setVisibility(View.VISIBLE);headLastUpdate.setVisibility(View.VISIBLE);headArrow.clearAnimation();headArrow.startAnimation(reverseAnimation);headTitle.setText("松开可以刷新");break;caseREFRESHING:headArrow.setVisibility(View.GONE);progressBar.setVisibility(View.VISIBLE);headTitle.setVisibility(View.VISIBLE);headLastUpdate.setVisibility(View.VISIBLE);headArrow.clearAnimation();headTitle.setText("正在刷新...");headView.setPadding(0,0,0,0);break;caseDONE:headArrow.setVisibility(View.VISIBLE);progressBar.setVisibility(View.GONE);headTitle.setVisibility(View.VISIBLE);headLastUpdate.setVisibility(View.VISIBLE);headArrow.clearAnimation();headTitle.setText("下拉可以刷新");headView.setPadding(0,-1*headContentHeight,0,0);break;}}privateintlastPos;//最后一个可见的item的位置privateintcount;//item总数,注意不是当前可见的item总数privatebooleanhasFoot=false;//是否有了Foot@OverridepublicvoidonScroll(AbsListViewview,intfirstVisibleItem,intvisibleItemCount,inttotalItemCount){firstVisibleIndex=firstVisibleItem;lastPos=getLastVisiblePosition();count=totalItemCount;//因为刚进入的时候,lastPos=-1,count=0,这个时候不能让它执行onAddFoot方法if(lastPos==count-1&&!hasFoot&&lastPos!=-1){hasFoot=true;onAddFoot();Log.d("addFoot================","执行添加Foot....");}Log.d("count================",count+"");Log.d("lastPos================",lastPos+"");}@OverridepublicvoidonScrollStateChanged(AbsListViewview,intscrollState){if(isFootLoading)return;if(hasFoot&&scrollState==SCROLL_STATE_IDLE){isFootLoading=true;onFootLoading();}}/***设置下拉刷新监听**@paramlistener*/publicvoidsetOnRefreshListner(OnRefreshListnerlistener){//设置下拉刷新可用isRefreshable=true;refreshListner=listener;}//执行底部加载publicvoidonFootLoading(){if(footLoadingListener!=null&&isFootLoading)footLoadingListener.onFootLoading();}publicvoidsetOnAddFootListener(OnAddFootListeneraddFootListener){onAddFootListener=addFootListener;}//执行添加footpublicvoidonAddFoot(){if(onAddFootListener!=null&&hasFoot)onAddFootListener.addFoot();}//是否添加Foot的监听器,如果写在OnFootLoadingListener中会有延迟,效果不好//应该是先进入添加Foot的状态,再进入FootLoading的状态publicOnAddFootListeneronAddFootListener;//是否进入从底部加载数据的状态的监听器publicOnFootLoadingListenerfootLoadingListener;//正在加载底部数据privatebooleanisFootLoading=false;publicvoidsetOnFootLoadingListener(OnFootLoadingListenerfootLoading){footLoadingListener=footLoading;}/***下拉刷新监听器*@authorlxj**/publicinterfaceOnRefreshListner{/***下拉刷新的时候,在这里执行获取数据的过程*/voidonRefresh();}/***上拉刷新监听器*@authorlxj**/publicinterfaceOnFootLoadingListener{/***这里是执行后台获取数据的过程*/voidonFootLoading();}/***添加Foot的监听器*@authorlxj**/publicinterfaceOnAddFootListener{/***这里是用户addFootView的操作*/voidaddFoot();}/***底部数据加载完成,用户需要加入一个removeFootView的操作*/publicvoidonFootLoadingComplete(){hasFoot=false;isFootLoading=false;}/***上拉刷新完成时所执行的操作,更改状态,隐藏head*/publicvoidonRefreshComplete(){state=DONE;changeHeadViewOfState();headLastUpdate.setText("最后刷新时间:"+newDate().toLocaleString());}@OverridepublicvoidsetAdapter(ListAdapteradapter){headLastUpdate.setText("最后刷新时间:"+newDate().toLocaleString());super.setAdapter(adapter);}}
下面是布局文件:
main.xml
<?xmlversion="1.0"encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="fill_parent"android:layout_height="fill_parent"android:orientation="vertical"><com.test.custom.CustomListViewandroid:layout_width="fill_parent"android:layout_height="fill_parent"android:id="@+id/listview"/></LinearLayout>
head.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp" >
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true" >
<ImageView
android:id="@+id/head_arrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@drawable/arrow" />
<ProgressBar
android:id="@+id/progressbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="gone" />
</FrameLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:gravity="center_horizontal"
android:orientation="vertical" >
<TextView
android:id="@+id/head_title"
android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="下拉可以刷新"android:textColor="#666666"android:textSize="20sp"/><TextViewandroid:id="@+id/head_last_update"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="3dp"android:text="最后更新时间:"android:textColor="#666666"android:textSize="10sp"/></LinearLayout></RelativeLayout></LinearLayout>
footer.xml
<?xmlversion="1.0"encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="horizontal"android:gravity="center"><ProgressBarandroid:layout_width="wrap_content"android:layout_height="wrap_content"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:paddingLeft="10dip"android:text="正在加载中..."android:textSize="20sp"/></LinearLayout>
本着一条龙服务的原则, 下面连箭头图片都给你搞上...箭头就在前面那个空格区域(3个点的后面),晕啊,箭头是白色的看不到,,,你在那里用鼠标拖一下就出来了,或者到我空间相册下载....
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。