登录 立即注册
安币:

查看: 105|回复: 6

android开发教程之实现listview下拉刷新和上拉刷新效果

[复制链接]

357

主题

427

帖子

1769

安币

手工艺人

发表于 2018-2-10 10:30:27 | 显示全部楼层 |阅读模式

            

        复制代码 代码如下:public class pulltoloadlistview extends listview implements onscrolllistener {

        private static final string tag = pulltoloadlistview.class.getsimplename();

        private static final int state_non = 0;private static final int state_pull_to_refresh = 1;private static final int state_release_to_refresh = 2;private static final int state_refreshing = 3;

        private int state;

        private int firstvisibleitem;private int lastvisisibleitem;

        private float prevy = 0;

        private view headerview;private view footerview;

        // header widgetsprivate progressbar headerprogressbar;private imageview headerimagearrow;private textview headertext;private rotateanimation headerarrowanim;private rotateanimation headerarrowreverseanim;// footer widgetsprivate progressbar footerprogressbar;private textview footertext;

        private boolean headerishanding = false;private boolean footerishanding = false;

        private int headerheight;private int footerheight;

        private resetanimation resetanim;

        private onloadinglistener onloadinglistener;private onscrolllistener onscrolllistener;

        public pulltoloadlistview(context context) {super(context);init(context);}

        public pulltoloadlistview(context context, attributeset attrs) {super(context, attrs);init(context);}

        private void init(context context) {state = state_non;firstvisibleitem = 0;lastvisisibleitem = 0;

        layoutinflater inflater = layoutinflater.from(context);headerview = inflater.inflate(r.layout.view_pull_header, null);footerview = inflater.inflate(r.layout.view_pull_footer, null);

        headerprogressbar = (progressbar) headerview.findviewbyid(r.id.progressbar);headerimagearrow = (imageview) headerview.findviewbyid(r.id.arrow);headertext = (textview) headerview.findviewbyid(r.id.text);headerarrowanim = new rotateanimation(0, -180, animation.relative_to_self, 0.5f, animation.relative_to_self, 0.5f);headerarrowanim.setduration(300);headerarrowanim.setfillafter(true);headerarrowreverseanim = new rotateanimation(-180, 0, animation.relative_to_self, 0.5f, animation.relative_to_self, 0.5f);headerarrowreverseanim.setduration(300);headerarrowreverseanim.setfillafter(true);

        footerprogressbar = (progressbar) footerview.findviewbyid(r.id.progressbar);footertext = (textview) footerview.findviewbyid(r.id.text);

        measureview(headerview);measureview(footerview);headerheight = headerview.getmeasuredheight();footerheight = footerview.getmeasuredheight();headerview.setpadding(0, -1 * headerview.getmeasuredheight(), 0, 0);footerview.setpadding(0, -1 * footerview.getmeasuredheight(), 0, 0);headerview.invalidate();footerview.invalidate();addheaderview(headerview, null, false);addfooterview(footerview, null, false);

        super.setonscrolllistener(this);}

        private void measureview(view view) {viewgroup.layoutparams lp = view.getlayoutparams();if(lp == null) {lp = new viewgroup.layoutparams(viewgroup.layoutparams.match_parent, viewgroup.layoutparams.wrap_content);}int childwidthspec = viewgroup.getchildmeasurespec(0, 0, lp.width);int childheightspec;if(lp.height > 0) {childheightspec = measurespec.makemeasurespec(0, measurespec.exactly);} else {childheightspec = measurespec.makemeasurespec(0, measurespec.unspecified);}view.measure(childwidthspec, childheightspec);}

        private void resetheader() {//headerview.setpadding(0, -1 * headerheight, 0, 0);resetanim = new resetanimation(headerview, headerheight, headerview.getpaddingtop());resetanim.start();}

        private void resetfooter() {resetanim = new resetanimation(footerview, footerheight, footerview.getpaddingtop());resetanim.start();}

        private void changeheaderviewbystate(int state) {if(this.state == state) {return ;}int prevstate = this.state;this.state = state;

        switch(state) {case state_non:headerprogressbar.setvisibility(view.invisible);headerimagearrow.setvisibility(view.visible);headerimagearrow.clearanimation();headertext.settext("pull down to refresh");break;case state_pull_to_refresh:headerprogressbar.setvisibility(view.invisible);headerimagearrow.setvisibility(view.visible);headertext.settext("pull down to refresh");if(prevstate == state_release_to_refresh) {headerimagearrow.startanimation(headerarrowreverseanim);} else {headerimagearrow.clearanimation();}break;case state_release_to_refresh:headerprogressbar.setvisibility(view.invisible);headerimagearrow.setvisibility(view.visible);headerimagearrow.startanimation(headerarrowanim);headertext.settext("release to refresh");break;case state_refreshing:headerprogressbar.setvisibility(view.visible);headerimagearrow.setvisibility(view.invisible);headerimagearrow.clearanimation();headertext.settext("refreshing");break;default:break;}}

        private void changefooterviewbystate(int state) {if(this.state == state) {return ;}this.state = state;

        switch(state) {case state_non:footerprogressbar.setvisibility(view.invisible);footertext.settext("pull up to refresh");break;case state_pull_to_refresh:footerprogressbar.setvisibility(view.invisible);footertext.settext("pull up to refresh");break;case state_release_to_refresh:footerprogressbar.setvisibility(view.invisible);footertext.settext("release to refresh");break;case state_refreshing:footerprogressbar.setvisibility(view.visible);footertext.settext("refreshing");break;default:break;}}

        @overridepublic void setonscrolllistener(onscrolllistener l) {this.onscrolllistener = l;}

        public void setonloadinglistener(onloadinglistener onloadinglistener) {this.onloadinglistener = onloadinglistener;}

        public void loadcompleted() {if(headerishanding) {changeheaderviewbystate(state_non);resetheader();headerishanding = false;}if(footerishanding) {changefooterviewbystate(state_non);resetfooter();footerishanding = false;}}

        private void handlemoveheaderevent(motionevent ev) {headerishanding = true;float tempy = ev.getrawy();float vector = tempy - prevy;vector /= 2;prevy = tempy;if(vector > 0) {int newpadding = (int) (headerview.getpaddingtop() + vector);newpadding = math.min(newpadding, headerheight / 2);headerview.setpadding(0, newpadding, 0, 0);if(state != state_refreshing) {if(newpadding > 0) {changeheaderviewbystate(state_release_to_refresh);} else {changeheaderviewbystate(state_pull_to_refresh);}}} else {if(state == state_release_to_refresh || state == state_pull_to_refresh) {int newpadding = (int) (headerview.getpaddingtop() + vector);newpadding = math.max(newpadding, -1 * headerheight);headerview.setpadding(0, newpadding, 0, 0);if(newpadding <= -1 * headerheight) {changeheaderviewbystate(state_non);headerishanding = false;} else if(newpadding <= 0) {changeheaderviewbystate(state_pull_to_refresh);} else {}}}}

        private void handlemovefooterevent(motionevent ev) {footerishanding = true;float tempy = ev.getrawy();float vector = tempy - prevy;vector /= 2;prevy = tempy;if(vector < 0) {int newpadding = (int) (footerview.getpaddingtop() - vector);if(newpadding > 0) {newpadding = 0;}footerview.setpadding(0, newpadding, 0, 0);if(state != state_refreshing) {if(newpadding < 0) {changefooterviewbystate(state_pull_to_refresh);} else {changefooterviewbystate(state_release_to_refresh);}}} else {int newpadding = (int) (footerview.getpaddingtop() - vector);newpadding = math.min(newpadding, footerheight);footerview.setpadding(0, newpadding, 0, 0);if(newpadding <= -1 * footerheight) {changefooterviewbystate(state_non);footerishanding = false;} else if(newpadding < 0) {changefooterviewbystate(state_pull_to_refresh);}}}

        @overridepublic boolean ontouchevent(motionevent ev) {switch(ev.getaction()) {case motionevent.action_down:prevy = ev.getrawy();break;case motionevent.action_up:if(state == state_release_to_refresh) {if(headerishanding) {changeheaderviewbystate(state_refreshing);if(onloadinglistener != null) {onloadinglistener.onloadnew();}}if(footerishanding) {changefooterviewbystate(state_refreshing);if(onloadinglistener != null) {onloadinglistener.onloadmore();}}} else if(state == state_pull_to_refresh) {if(headerishanding) {changeheaderviewbystate(state_non);resetheader();headerishanding = false;}if(footerishanding) {changefooterviewbystate(state_non);resetfooter();footerishanding = false;}} else if(state == state_non) {headerishanding = false;footerishanding = false;} else {// state == state_refreshing// ignore}break;case motionevent.action_move:if(resetanim == null || !resetanim.run) {if(state != state_refreshing) {adapter adapter = getadapter();if(adapter == null) {handlemoveheaderevent(ev);} else {final int count = adapter.getcount();if(count <= 0) {handlemoveheaderevent(ev);} else {float tempy = ev.getrawy();float vector = tempy - prevy;if(firstvisibleitem == 0 && lastvisisibleitem == count - 1) {if(headerishanding) {handlemoveheaderevent(ev);} else if(footerishanding) {handlemovefooterevent(ev);} else {if(vector > 0) {handlemoveheaderevent(ev);} else if(vector < 0) {handlemovefooterevent(ev);} else {// ignore vector == 0}}} else if(firstvisibleitem == 0 && vector > 0) {handlemoveheaderevent(ev);} else if(lastvisisibleitem == count - 1 && vector < 0) {handlemovefooterevent(ev);} else {// ignore}}}}}break;default:break;}return super.ontouchevent(ev);}

        @overridepublic void onscrollstatechanged(abslistview view, int scrollstate) {if(onscrolllistener != null) {onscrolllistener.onscrollstatechanged(view, scrollstate);}}

        @overridepublic void onscroll(abslistview view, int firstvisibleitem,int visibleitemcount, int totalitemcount) {this.firstvisibleitem = firstvisibleitem;this.lastvisisibleitem = firstvisibleitem + visibleitemcount - 1;if(onscrolllistener != null) {onscrolllistener.onscroll(view, firstvisibleitem, visibleitemcount, totalitemcount);}}

        static class resetanimation extends thread {

        static final int duration = 600;

        static final int interval = 5;

        view view;int orignalheight;int paddingtop;

        boolean run = false;

        resetanimation(view view, int orignalheight, int paddingtop) {this.view = view;this.orignalheight = orignalheight;this.paddingtop = paddingtop;}

        public void run() {run = true;int total = orignalheight * 2 + paddingtop;int timetotal = duration / interval;int piece = total / timetotal;int time = 0;final view view = this.view;final int paddingtop = this.paddingtop;do {final int nextpaddingtop = paddingtop - time * piece;view.post(new runnable() {public void run() {view.setpadding(0, nextpaddingtop, 0, 0);view.postinvalidate();}});try {sleep(interval);} catch (interruptedexception e) {e.printstacktrace();}time ++;} while(time < timetotal);run = false;}}

        public interface onloadinglistener {

        public void onloadnew();

        public void onloadmore();}



        

20

主题

8711

帖子

2453

安币

Android大神

Rank: 6Rank: 6

发表于 2018-2-11 16:54:13 | 显示全部楼层
感觉楼主很用心,辛苦啦~

367

主题

420

帖子

1827

安币

手工艺人

发表于 2018-2-12 17:30:24 | 显示全部楼层
安卓巴士是个不错的网站,我来顶个贴~

350

主题

418

帖子

1746

安币

手工艺人

发表于 2018-2-13 04:21:35 | 显示全部楼层
楼主威武,以后多发干货,多办活动~!

2

主题

8898

帖子

2577

安币

Android大神

Rank: 6Rank: 6

发表于 2018-2-13 12:13:38 | 显示全部楼层
感觉楼主很用心,辛苦啦~

2

主题

9042

帖子

2187

安币

Android大神

Rank: 6Rank: 6

QQ达人

发表于 2018-2-13 21:34:39 | 显示全部楼层
支持,感谢,祝巴士越来越好~

3

主题

8933

帖子

1894

安币

Android大神

Rank: 6Rank: 6

QQ达人

发表于 2018-2-14 00:46:03 | 显示全部楼层
感谢分享,安卓巴士有你更精彩:lol
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

站长推荐

通过邮件订阅最新安卓weekly信息
上一条 /4 下一条

下载安卓巴士客户端

全国最大的安卓开发者社区
联系我们
关闭
合作电话:
13802416937
Email:
435399051@qq.com
商务市场合作/投稿
问题反馈及帮助
联系我们

广告投放| 下载客户端|申请友链|手机版|站点统计|安卓巴士 ( 粤ICP备15117877号 )

快速回复 返回顶部 返回列表