布局:

<com.example.administrator.d30_myrefreshlistview.RefreshListView
android:id="@+id/refresh_listview"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginBottom="10dp"
>
<ImageView
android:id="@+id/image_arrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/indicator_arrow"
android:layout_centerInParent="true"
/>
<ProgressBar
android:id="@+id/pb_rotate"
android:layout_width="30dp"
android:layout_height="30dp"
android:indeterminate="false"
android:indeterminateDuration="1000"
android:indeterminateDrawable="@drawable/indecate_rotate"
android:layout_centerInParent="true"
android:visibility="invisible"
/>
</RelativeLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
>
<TextView
android:id="@+id/tv_state"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:textColor="#aa000000"
android:text="下拉刷新"
android:layout_marginBottom="10dp"
/>
<TextView
android:id="@+id/tv_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
android:textColor="@android:color/darker_gray"
android:text="最后刷新"
android:layout_marginBottom="10dp"
/>
</LinearLayout>
<ProgressBar
android:layout_width="30dp"
android:layout_height="30dp"
android:id="@+id/pb_rotate_footer"
android:indeterminateDrawable="@drawable/indecate_rotate"
android:indeterminateDuration="1000"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="正在加载..."
android:textSize="20sp"
android:textColor="#aa000000"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"/>

代码:

/*
1:创建集合,准备数据。
2:创建适配器。
3:设置适配器。
*/
public class MainActivity extends AppCompatActivity {
private RefreshListView listview;
private List<String> strs;
private MyAdapter adapter;
private boolean flag = true;//true表示下拉刷新,false表示上拉加载。
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
//下载数据已经完成。
//更新界面。
adapter.notifyDataSetChanged();
//RefreshListView界面要还原初始状态。
listview.completeView();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listview = (RefreshListView) findViewById(R.id.refresh_listview);
//添加监听
listview.setOnRefreshListener(new RefreshListView.onRefreshListener() {
@Override
public void onPullRefresh() {
//模拟请求网络数据。
requestDataFromServer(true);
} @Override
public void onLoadMore() {
//模拟请求下一页网络数据。
requestDataFromServer(false);
}
});
initData();
adapter = new MyAdapter();
listview.setAdapter(adapter);
} private void requestDataFromServer(final boolean flag) {
new Thread(new Runnable() {
@Override
public void run() {
SystemClock.sleep(3000);
//1;添加新的数据。
if(flag) {
strs.add(0, "下拉刷新的数据");
//2;通知ui线程更新界面。
handler.sendEmptyMessage(1);
}else{
//上拉加载。
strs.add("加载更多的数据"+1);
strs.add("加载更多的数据"+2);
strs.add("加载更多的数据"+3);
handler.sendEmptyMessage(1);
}
}
}).start();
} private void initData() {
strs = new ArrayList<String>();
for(int i=0;i<18;i++){
strs.add("listview 原来的数据"+i);
}
}
class MyAdapter extends BaseAdapter{ @Override
public int getCount() {
return strs.size();
} @Override
public Object getItem(int position) {
return strs.get(position);
} @Override
public long getItemId(int position) {
return position;
} @Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView item_view = new TextView(MainActivity.this);
item_view.setPadding(0,10,0,10);
//设置字体
item_view.setTextSize(20);
//设置内容
item_view.setText(strs.get(position));
return item_view;
}
}
}
public class RefreshListView extends ListView implements AbsListView.OnScrollListener {
private View headerView;
private int headerView_height;
private int down_y;//按下的时候y的坐标
private static final int PULL_REFRESH = 0;//表示下拉刷新--允许下拉刷新
private static final int RELEASE_REFRESH = 1;//表示松开刷新--允许松开刷新
private static final int REFRESHING = 2;//表示正在刷新--头部完全显示。---正在请求网络数据。
private int current_state = PULL_REFRESH;//最初状态
private ImageView image_arrow;//箭头控件
private TextView tv_state, tv_time;//状态文本框,时间文本显示框。
private ProgressBar pb_rotate;//旋转动画。
private RotateAnimation downAnimation, upAnimation;
private int padding_top;//表示headview的padding_top;
private onRefreshListener listener;//使用者传过来的实现的对象。
private View footView;//底部控件。
private int footView_height;//底部控件的高度。
public RefreshListView(Context context) {
super(context);
init();
} public RefreshListView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
} private void init() {
//设置监听
setOnScrollListener(this);
initHeaderView();
initRotateAnimation();//创建2个动画
initFooterView();
} private void initFooterView() {
footView = View.inflate(getContext(),R.layout.layout_footer,null);
footView.measure(0, 0);
footView_height =footView.getMeasuredHeight();
//设置隐藏
footView.setPadding(0, -footView_height, 0, 0);
addFooterView(footView);
} private void initRotateAnimation() {
//往下动画。
downAnimation = new RotateAnimation(0, -180, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);
downAnimation.setDuration(300);
downAnimation.setFillAfter(true);
//往上动画
upAnimation = new RotateAnimation(-180, -360, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);
upAnimation.setDuration(300);
upAnimation.setFillAfter(true);
} private void initHeaderView() {
headerView = View.inflate(getContext(), R.layout.layout_header, null);
image_arrow = (ImageView) headerView.findViewById(R.id.image_arrow);
tv_state = (TextView) headerView.findViewById(R.id.tv_state);
tv_time = (TextView) headerView.findViewById(R.id.tv_time);
pb_rotate = (ProgressBar) headerView.findViewById(R.id.pb_rotate);
//设置头部控件的一些属性。--下拉刷新主要是通过更改头部控件的padding值来隐藏和显示的。
//先要计算头部控件的高度。
headerView.measure(0, 0);//先执行onMearsure();
headerView_height = headerView.getMeasuredHeight();
headerView.setPadding(0, -headerView_height, 0, 0);//隐藏头部
//添加给listview.
addHeaderView(headerView);
} @Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
down_y = (int) ev.getY();
//按下状态
break;
case MotionEvent.ACTION_MOVE:
//滑动的状态
//1:获得当前的y坐标
int y = (int) ev.getY();
//2:计算滑动了多远。
int delta_y = y - down_y;//往下滑delta_y>0,,往上滑 delta_y<0
padding_top = delta_y + (-headerView_height);
//将值设置给头部控件。
if (padding_top > -headerView_height) {//说明头部要么正好隐藏要么显示一部分或者更多。
headerView.setPadding(0, padding_top, 0, 0);
if (padding_top >= 0 && current_state == PULL_REFRESH) {
current_state = RELEASE_REFRESH;//松开刷新。
//变化
//1:箭头往上执行动画
//2:文字改变。----tv_state---松开刷新。
refreshView();
} else if (padding_top < 0 && current_state == RELEASE_REFRESH) {
current_state = PULL_REFRESH;
//变化
// 1:箭头往下执行动画
//2:文字改变---下拉刷新
refreshView();
}
return true;//消费这个事件。意思就是让listview不要有滚动的行为,杜绝listview滚动。 }
break;
case MotionEvent.ACTION_UP:
//松开的状态
if(current_state==PULL_REFRESH){
//隐藏
headerView.setPadding(0,-headerView_height,0,0);
}else if(current_state==RELEASE_REFRESH){
//更改状态。
current_state = REFRESHING;
//更新界面。
refreshView();
//5:要请求网络数据,
if(listener!=null){
listener.onPullRefresh();//请求新的数据。
}
}
break;
}
return super.onTouchEvent(ev);
}
private boolean flag;//true表示数据已经显示完。
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if(scrollState==SCROLL_STATE_IDLE && flag){
isLoadMore = true;
//请求下一页
//1:底部要显示。
footView.setPadding(0,0,0,0);
//2:请求下一页数据。
if(listener!=null){
listener.onLoadMore();
}
}
} @Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
flag = firstVisibleItem+visibleItemCount==totalItemCount;
} public interface onRefreshListener{
void onPullRefresh();
void onLoadMore();
}
public void setOnRefreshListener(onRefreshListener listener){
this.listener = listener;
}
private void refreshView() {
switch (current_state) {
case RELEASE_REFRESH:
//动画
//1:箭头往上执行动画
image_arrow.startAnimation(upAnimation);
//2:文字改变。----tv_state---松开刷新。
tv_state.setText("松开刷新");
break;
case PULL_REFRESH:
// 1:箭头往下执行动画
image_arrow.startAnimation(downAnimation);
//2:文字改变---下拉刷新
tv_state.setText("下拉刷新");
break;
case REFRESHING:
//1:头部要正常显示。
headerView.setPadding(0, 0, 0, 0);
//2:箭头隐藏
image_arrow.setVisibility(INVISIBLE);
//3:进度条显示。
pb_rotate.setVisibility(VISIBLE);
//4:文字更改。
tv_state.setText("正在刷新");
break; }
}
private boolean isLoadMore;//true表示上拉加载,false表示下拉刷新。
//还原初始化状态。
public void completeView(){
if(!isLoadMore) {
//1:箭头要显示。
image_arrow.clearAnimation();//这个时候有可能箭头有可能在执行动画。将动画进行清除。
image_arrow.setVisibility(VISIBLE);
//2:进度动画要隐藏
pb_rotate.setVisibility(INVISIBLE);
//3:tv_state文字改变为下拉刷新。
tv_state.setText("下拉刷新");
//4;状态---更改为下拉刷新。
current_state = PULL_REFRESH;
//5:tv_time更改为当前的时间
tv_time.setText(getTime());
//隐藏
headerView.setPadding(0, -headerView_height, 0, 0);
}else{
footView.setPadding(0,-footView_height,0,0);
isLoadMore = false;
// 定位到最后一条。
setSelection(getCount()-1);//定位到最后一条数据。
}
}
private String getTime(){
SimpleDateFormat format = new SimpleDateFormat("yyyy MM dd HH:mm:ss");
return format.format(new Date());
}
}

RefreshListView下拉刷新的更多相关文章

  1. 【框架】RefreshListView下拉刷新

    布局: <com.example.administrator.d30_myrefreshlistview.RefreshListView android:id="@+id/refres ...

  2. ListView下拉刷新上拉加载更多实现

    这篇文章将带大家了解listview下拉刷新和上拉加载更多的实现过程,先看效果(注:图片中listview中的阴影可以加上属性android:fadingEdge="none"去掉 ...

  3. react-native 模仿原生 实现下拉刷新/上拉加载更多(RefreshListView)

    1.下拉刷新/上拉加载更多 组件(RefreshListView) src/components/RefreshListView/index.js /** * 下拉刷新/上拉加载更多 组件(Refre ...

  4. Android--ListView下拉刷新

    整理了下以前写的小项目,ListView的下拉刷新,虽然小但还是想纪念下..适合新手看,大神略过... 效果图:     代码:  实体类 package com.example.listviewre ...

  5. Android下拉刷新底部操作栏的隐藏问题

    最近自己编写下拉刷新的时候,发现了一个问题,就是有一个需求是这样的:要求页面中是一个Tab切换界面,一个界面有底部操作栏,不可下拉刷新,另一个界面没有底部操作栏,但可以下拉刷新. 按照平常的做法,我在 ...

  6. android 项目学习随笔十一(ListView下拉刷新提示)

    1. 设置mHeaderView.setPadding TOPPADING为负值,隐藏刷新提示头布局 在onTouchEvent事件中进行头布局显示隐藏切换 import java.text.Simp ...

  7. android124 zhihuibeijing 新闻中心-新闻 -北京页签 下拉刷新

    缓存工具类:以url为key,json数据为value, package com.itheima.zhbj52.utils; import com.itheima.zhbj52.global.Glob ...

  8. Android 它们的定义ListView实现底部和页下拉刷新刷新的顶

    在项目开发.由于数据量过大,寻呼需要加载或下拉刷新.为了缓解长期等待-time负载.这个博客的评论中被自己的定义实例ListView实现底部的下拉刷新页面正在加载结果和顶部. 其效果图: 一.List ...

  9. google官方的下拉刷新+自定义上拉加载更多

    转载请标注转载:http://blog.csdn.net/oqihaogongyuan/article/details/50949118 google官方的下拉刷新+自定义上拉加载更多 现在很多app ...

随机推荐

  1. 2017CCPC秦皇岛 L题One-Dimensional Maze&&ZOJ3992【模拟】

    链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3992 题意: 走迷宫,一个一维字符串迷宫,由'L'.'R'组成,分别 ...

  2. IO流总结笔记二

    ​ Reader |--InputStreamReader |--FileReader:专门用于处理文件的字符读取流对象 Writer |--OutputStreamWriter |--FileWri ...

  3. 利用 python requests完成接口文件上传

    最近在准备一个公开课,主题就是利用不同的语言和不同的工具去实现文件的上传和下载. 在利用Jmeter去实现功能的时候,以及利用loadrunner去写脚本的时候,都很顺利,没有任何问题,当我尝试用Py ...

  4. SpringBoot整合Jest操作ES

    (1).添加依赖 <dependency> <groupId>io.searchbox</groupId> <artifactId>jest</a ...

  5. C++学习8-面向对象编程基础(模板)

    模板 模板是一种工具,模板可以使程序员能建立具有通用类型的函数库与类库: 模板具有两种不同的形式: 函数模板 类模板 函数模板 当一个add()函数接收两个参数,因为某种特定情况,所传入的实参数据类型 ...

  6. adboost方法(转载)

    转载链接:http://blog.csdn.net/google19890102/article/details/46376603 一.集成方法(Ensemble Method)     集成方法主要 ...

  7. Linux命令学习总结:date命令【转】

    本文转自:http://www.cnblogs.com/kerrycode/p/3427617.html 命令简介: date 根据给定格式显示日期或设置系统日期时间.print or set the ...

  8. springboot系列十二、springboot集成RestTemplate及常见用法

    一.背景介绍 在微服务都是以HTTP接口的形式暴露自身服务的,因此在调用远程服务时就必须使用HTTP客户端.我们可以使用JDK原生的URLConnection.Apache的Http Client.N ...

  9. saltstack自动化运维系列⑤之saltstack的配置管理详解

    saltstack自动化运维系列⑤之saltstack的配置管理详解 配置管理初始化: a.服务端配置vim /etc/salt/master file_roots: base: - /srv/sal ...

  10. [java]用md5来判断两个文件是否完全相同

    1. 前言 由于相比较两张图片是否是相同,如果通过像素点比较感觉速度比较慢,当很多图片进行比较时,效率就低很多了.由于每个文件md5基本上是唯一的,所以用获取文件的md5来判断是否相同文件. 2. 代 ...