布局:

<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. dubbo集群服务下一台服务挂了对服务调用的影响

    一.问题描述:项目中2台dubbo服务给移动端提供查询接口,移动端反应说查询时而很快(秒刷),时而很慢(4-5秒). 二.问题分析: 1.问题猜想:网络不稳定原因导致,但是切换公司wifi和手机4G, ...

  2. CF448C Painting Fence (贪心分治)

    题面 \(solution:\) 一道蛮水的分治题,但思想很不错(虽然我还是非常天真的以为是积木大赛原题,并且居然还有30分) 看到这个题目,根据贪心的一贯风格,我们肯定能想到将整个栅栏的下面某部分直 ...

  3. ubuntu 上下左右键变成ABCD

    1.在ubuntu终端环境出现: 这表示你正在insert mode.... 按esc,回到command mode,上下左右就回复到正常的方向键功能了 2.可能写的程序是在insert mode(r ...

  4. Informatic学习总结_day03

    1.update strategy

  5. python渗透

    计划写一个获取qq空间加密相册的工具. 分析: 她的相册密码是手机号,先写一个生成手机号的脚本 空间有她之前的手机号,那么她现在的手机号也极有可能是一样的运营商,比如移动(缩小密码范围) 自己新建一个 ...

  6. Django开发笔记五

    Django开发笔记一 Django开发笔记二 Django开发笔记三 Django开发笔记四 Django开发笔记五 Django开发笔记六 1.页面继承 定义base.html: <!DOC ...

  7. ubuntu 禁用自带的nouveau显卡驱动,安装NVIDIA显卡驱动

    下载显卡驱动 进入Nvidia的官网,找到对应GTX 750显卡的Linux 64-bit 的驱动程序,然后下载 当点击下载链接后,发现浏览器一直在加载那个*.run文件,很久都加载不完.这时将浏览器 ...

  8. 不断更新的 ToDo-List

    有些事情要明着写出来才会去干. 这里是一个不断更新的 ToDo-List,大致按照重要度和列出时间排序,已经完成的会画上删除线. 主要着眼短期计划,其中的大部分事务应该在一周内解决,争取不做一只鸽子. ...

  9. Dubbo本地存根

    在远程调用服务提供者的实现之前,如果需要做一些参数验证.缓存.判断.小功能等等,满足要求再调用服务提供者的远程服务,则我们可以通过编写一个本地存根来实现这种功能. (1).在公共项目中或服务消费者项目 ...

  10. NMS和soft-nms算法

    非极大值抑制算法(nms) 1. 算法原理 非极大值抑制算法(Non-maximum suppression, NMS)的本质是搜索局部极大值,抑制非极大值元素. 2. 3邻域情况下NMS的实现 3邻 ...