Android带刷新时间显示的PullToRefresh上下拉刷新
程序员文章站
2023-02-07 15:38:58
用过很多上下拉刷新,找到一个让自己满意的确实不容易,有些好的刷新控件,也并不是公司所需要的,在这里我给大家推荐一下我所喜欢的上下拉控件,实现也挺简单,需要的不妨来用一下,效...
用过很多上下拉刷新,找到一个让自己满意的确实不容易,有些好的刷新控件,也并不是公司所需要的,在这里我给大家推荐一下我所喜欢的上下拉控件,实现也挺简单,需要的不妨来用一下,效果一看便知
加载就是一个圆形进度条,一个正在加载textview,我就不上图了
这个是刷新的头布局
<?xml version="1.0" encoding="utf-8"?> <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <framelayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="10dip" > <imageview android:id="@+id/iv_listview_header_arrow" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:minwidth="30dip" android:src="@mipmap/ic_launcher" /> <progressbar android:id="@+id/pb_listview_header" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:indeterminatedrawable="@drawable/common_progressbar" android:visibility="gone" /> </framelayout> <linearlayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:gravity="center_horizontal" android:orientation="vertical" > <textview android:id="@+id/tv_listview_header_state" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="下拉刷新" android:textcolor="#ff0000" android:textsize="18sp" /> <textview android:id="@+id/tv_listview_header_last_update_time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margintop="5dip" android:text="最后刷新时间: 2014-10-10 12:56:12" android:textsize="14sp" /> </linearlayout> </linearlayout>
这个是加载的底部局
<?xml version="1.0" encoding="utf-8"?> <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" > <linearlayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_margin="10dip" android:gravity="center_vertical" android:orientation="horizontal" > <progressbar android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:indeterminatedrawable="@drawable/common_progressbar" /> <textview android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginleft="10dip" android:text="加载更多..." android:textcolor="#ff0000" android:textsize="18sp" /> </linearlayout> </linearlayout>
下面是运行布局嵌套的listview布局,如果使用请换一下包名
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.constraintlayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="jiexinkeji.com.shuaxin.mainactivity"> <jiexinkeji.com.shuaxin.refreshlistview android:id="@+id/refreshlistview" android:layout_width="match_parent" android:layout_height="match_parent"></jiexinkeji.com.shuaxin.refreshlistview> </android.support.constraint.constraintlayout>
下面是在drawable文件夹下面创建的一个文件:
<?xml version="1.0" encoding="utf-8"?> <rotate xmlns:android="http://schemas.android.com/apk/res/android" android:fromdegrees="0" android:pivotx="50%" android:pivoty="50%" android:todegrees="360" > <shape android:innerradiusratio="3" android:shape="ring" android:uselevel="false" > <gradient android:centercolor="#ff6666" android:endcolor="#ff0000" android:startcolor="#ffffff" android:type="sweep" /> </shape> </rotate>
这个是定义的一个接口,有刷新和加载两个方法
package jiexinkeji.com.shuaxin; public interface onrefreshlistener { /** * 下拉刷新 */ void ondownpullrefresh(); /** * 上拉加载更多 */ void onloadingmore(); }
下面的类是继承自listview,来实现下拉刷新上啦加载
package jiexinkeji.com.shuaxin; import android.content.context; import android.support.v4.widget.swiperefreshlayout; import android.util.attributeset; import android.util.log; import android.view.motionevent; import android.view.view; import android.view.animation.animation; import android.view.animation.rotateanimation; import android.widget.abslistview; import android.widget.imageview; import android.widget.listview; import android.widget.progressbar; import android.widget.textview; import java.text.simpledateformat; public class refreshlistview extends listview implements abslistview.onscrolllistener { private static final string tag = "refreshlistview"; private int firstvisibleitemposition; // 屏幕显示在第一个的item的索引 private int downy; // 按下时y轴的偏移量 private int headerviewheight; // 头布局的高度 private view headerview; // 头布局的对象 private final int down_pull_refresh = 0; // 下拉刷新状态 private final int release_refresh = 1; // 松开刷新 private final int refreshing = 2; // 正在刷新中 private int currentstate = down_pull_refresh; // 头布局的状态: 默认为下拉刷新状态 private animation upanimation; // 向上旋转的动画 private animation downanimation; // 向下旋转的动画 private imageview ivarrow; // 头布局的剪头 private progressbar mprogressbar; // 头布局的进度条 private textview tvstate; // 头布局的状态 private textview tvlastupdatetime; // 头布局的最后更新时间 private onrefreshlistener monrefershlistener; private boolean isscrolltobottom; // 是否滑动到底部 private view footerview; // 脚布局的对象 private int footerviewheight; // 脚布局的高度 private boolean isloadingmore = false; // 是否正在加载更多中 public refreshlistview(context context, attributeset attrs) { super(context, attrs); initheaderview(); initfooterview(); this.setonscrolllistener(this); } /** * 初始化脚布局 */ private void initfooterview() { footerview = view.inflate(getcontext(), r.layout.listview_footer, null); footerview.measure(0, 0); footerviewheight = footerview.getmeasuredheight(); footerview.setpadding(0, -footerviewheight, 0, 0); this.addfooterview(footerview); } /** * 初始化头布局 */ private void initheaderview() { headerview = view.inflate(getcontext(), r.layout.listview_header, null); ivarrow = (imageview) headerview .findviewbyid(r.id.iv_listview_header_arrow); mprogressbar = (progressbar) headerview .findviewbyid(r.id.pb_listview_header); tvstate = (textview) headerview .findviewbyid(r.id.tv_listview_header_state); tvlastupdatetime = (textview) headerview .findviewbyid(r.id.tv_listview_header_last_update_time); // 设置最后刷新时间 tvlastupdatetime.settext("最后刷新时间: " + getlastupdatetime()); headerview.measure(0, 0); // 系统会帮我们测量出headerview的高度 headerviewheight = headerview.getmeasuredheight(); headerview.setpadding(0, -headerviewheight, 0, 0); this.addheaderview(headerview); // 向listview的顶部添加一个view对象 initanimation(); } /** * 获得系统的最新时间 * * @return */ private string getlastupdatetime() { simpledateformat sdf = new simpledateformat("yyyy-mm-dd hh:mm:ss"); return sdf.format(system.currenttimemillis()); } /** * 初始化动画 */ private void initanimation() { upanimation = new rotateanimation(0f, -180f, animation.relative_to_self, 0.5f, animation.relative_to_self, 0.5f); upanimation.setduration(500); upanimation.setfillafter(true); // 动画结束后, 停留在结束的位置上 downanimation = new rotateanimation(-180f, -360f, animation.relative_to_self, 0.5f, animation.relative_to_self, 0.5f); downanimation.setduration(500); downanimation.setfillafter(true); // 动画结束后, 停留在结束的位置上 } @override public boolean ontouchevent(motionevent ev) { switch (ev.getaction()) { case motionevent.action_down : downy = (int) ev.gety(); break; case motionevent.action_move : int movey = (int) ev.gety(); // 移动中的y - 按下的y = 间距. int diff = (movey - downy) / 2; // -头布局的高度 + 间距 = paddingtop int paddingtop = -headerviewheight + diff; // 如果: -头布局的高度 > paddingtop的值 执行super.ontouchevent(ev); if (firstvisibleitemposition == 0 && -headerviewheight < paddingtop) { if (paddingtop > 0 && currentstate == down_pull_refresh) { // 完全显示了. log.i(tag, "松开刷新"); currentstate = release_refresh; refreshheaderview(); } else if (paddingtop < 0 && currentstate == release_refresh) { // 没有显示完全 log.i(tag, "下拉刷新"); currentstate = down_pull_refresh; refreshheaderview(); } // 下拉头布局 headerview.setpadding(0, paddingtop, 0, 0); return true; } break; case motionevent.action_up : // 判断当前的状态是松开刷新还是下拉刷新 if (currentstate == release_refresh) { log.i(tag, "刷新数据."); // 把头布局设置为完全显示状态 headerview.setpadding(0, 0, 0, 0); // 进入到正在刷新中状态 currentstate = refreshing; refreshheaderview(); if (monrefershlistener != null) { monrefershlistener.ondownpullrefresh(); // 调用使用者的监听方法 } } else if (currentstate == down_pull_refresh) { // 隐藏头布局 headerview.setpadding(0, -headerviewheight, 0, 0); } break; default : break; } return super.ontouchevent(ev); } /** * 根据currentstate刷新头布局的状态 */ private void refreshheaderview() { switch (currentstate) { case down_pull_refresh : // 下拉刷新状态 tvstate.settext("下拉刷新"); ivarrow.startanimation(downanimation); // 执行向下旋转 break; case release_refresh : // 松开刷新状态 tvstate.settext("松开刷新"); ivarrow.startanimation(upanimation); // 执行向上旋转 break; case refreshing : // 正在刷新中状态 ivarrow.clearanimation(); ivarrow.setvisibility(view.gone); mprogressbar.setvisibility(view.visible); tvstate.settext("正在刷新中..."); break; default : break; } } /** * 当滚动状态改变时回调 */ @override public void onscrollstatechanged(abslistview view, int scrollstate) { if (scrollstate == scroll_state_idle || scrollstate == scroll_state_fling) { // 判断当前是否已经到了底部 if (isscrolltobottom && !isloadingmore) { isloadingmore = true; // 当前到底部 log.i(tag, "加载更多数据"); footerview.setpadding(0, 0, 0, 0); this.setselection(this.getcount()); if (monrefershlistener != null) { monrefershlistener.onloadingmore(); } } } } /** * 当滚动时调用 * * @param firstvisibleitem * 当前屏幕显示在顶部的item的position * @param visibleitemcount * 当前屏幕显示了多少个条目的总数 * @param totalitemcount * listview的总条目的总数 */ @override public void onscroll(abslistview view, int firstvisibleitem, int visibleitemcount, int totalitemcount) { firstvisibleitemposition = firstvisibleitem; if (getlastvisibleposition() == (totalitemcount - 1)) { isscrolltobottom = true; } else { isscrolltobottom = false; } } /** * 设置刷新监听事件 * * @param listener */ public void setonrefreshlistener(onrefreshlistener listener) { monrefershlistener = listener; } /** * 隐藏头布局 */ public void hideheaderview() { headerview.setpadding(0, -headerviewheight, 0, 0); ivarrow.setvisibility(view.visible); mprogressbar.setvisibility(view.gone); tvstate.settext("下拉刷新"); tvlastupdatetime.settext("最后刷新时间: " + getlastupdatetime()); currentstate = down_pull_refresh; } /** * 隐藏脚布局 */ public void hidefooterview() { footerview.setpadding(0, -footerviewheight, 0, 0); isloadingmore = false; } }
接下来再运行主activity使用就行了
package jiexinkeji.com.shuaxin; import android.app.activity; import android.graphics.color; import android.os.asynctask; import android.os.bundle; import android.os.systemclock; import android.view.view; import android.view.viewgroup; import android.widget.baseadapter; import android.widget.textview; import java.util.arraylist; import java.util.list; public class mainactivity extends activity implements onrefreshlistener { private list<string> textlist; private myadapter adapter; private refreshlistview rlistview; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); rlistview = (refreshlistview) findviewbyid(r.id.refreshlistview); textlist = new arraylist<string>(); for (int i = 0; i < 25; i++) { textlist.add("这是一条listview的数据" + i); } adapter = new myadapter(); rlistview.setadapter(adapter); rlistview.setonrefreshlistener(this); } private class myadapter extends baseadapter { @override public int getcount() { // todo auto-generated method stub return textlist.size(); } @override public object getitem(int position) { // todo auto-generated method stub return textlist.get(position); } @override public long getitemid(int position) { // todo auto-generated method stub return position; } @override public view getview(int position, view convertview, viewgroup parent) { // todo auto-generated method stub textview textview = new textview(mainactivity.this); textview.settext(textlist.get(position)); textview.settextsize(18.0f); return textview; } } @override public void ondownpullrefresh() { new asynctask<void, void, void>() { @override protected void doinbackground(void... params) { systemclock.sleep(2000); for (int i = 0; i < 2; i++) { textlist.add(0, "这是下拉刷新出来的数据" + i); } return null; } @override protected void onpostexecute(void result) { adapter.notifydatasetchanged(); rlistview.hideheaderview(); } }.execute(new void[]{}); } @override public void onloadingmore() { new asynctask<void, void, void>() { @override protected void doinbackground(void... params) { systemclock.sleep(5000); textlist.add("这是加载更多出来的数据1"); textlist.add("这是加载更多出来的数据2"); textlist.add("这是加载更多出来的数据3"); return null; } @override protected void onpostexecute(void result) { adapter.notifydatasetchanged(); // 控制脚布局隐藏 rlistview.hidefooterview(); } }.execute(new void[]{}); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
下一篇: 香港大屿山缆车价格 门票及相关介绍
推荐阅读