下拉刷新
一:下拉刷新
自定义控件:继承listview 在头部添加headerview 在底部添加footview
原理:下拉刷新就是继承listview 在头部添加headerview 本质是先将头布局隐藏 随着用户的动作将头布局显示出来并且改变头布局的状态。
用户移动时:首先判断必须是向下拉并且显示的第一条数据的索引为0
状态改变:当由下拉刷新状态改变为释放刷新状态 再变回下拉刷新状态
用户松开时:分两种情况:一种是在下拉刷新状态直接松开-------将头布局隐藏
一种是在释放刷新状态下松开----------将状态改变为正在刷新状态等
二:Android知识的学会标准
一个过程:了解----熟悉----熟练-----掌握
在我看来:应该是这样你顺着看书看的懂,学得会,你逆着不用看书查资料也会用=======表示你已经掌握这个知识了
三:下拉刷新部分代码:
public class RefreshedListView extends ListView implements OnScrollListener {
private View headerView;
private int downY;
private int headerViewHeight;
private final int PULL_REFRESH=0;
private final int RELEASE_REFRESH=1;
private final int REFRESHING=2;
private int headerViewCurrentState=PULL_REFRESH;
private ImageView iv_picture;
private ProgressBar pb;
private TextView tv_title;
private TextView tv_refreshtime;
private int firstVisibleItemPosition;
private RotateAnimation downAnimation;
private RotateAnimation upAnimation;
public RefreshedListView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
initHeader();
//设置滚动监听器
this.setOnScrollListener(this);
}
private void initHeader() {
//创建headerview
headerView = View.inflate(getContext(), R.layout.headerlayout, null);
//获取控件
iv_picture = (ImageView) headerView.findViewById(R.id.iv_picture);
pb = (ProgressBar) headerView.findViewById(R.id.pb_progressbar);
tv_title = (TextView) headerView.findViewById(R.id.tv_title);
tv_refreshtime = (TextView) headerView.findViewById(R.id.tv_refreshtime);
//让框架帮我们去测量头布局的宽和高
headerView.measure(0, 0);
headerViewHeight = headerView.getMeasuredHeight();
//设置位置
headerView.setPadding(0, -headerViewHeight, 0, 0);
this.addHeaderView(headerView);
initAnimation();
}
/**
* 旋转动画
*/
private void initAnimation() {
downAnimation = new RotateAnimation(0, -180, Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
downAnimation.setDuration(500);
downAnimation.setFillAfter(true);
upAnimation = new RotateAnimation(-180, -360, Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
upAnimation.setDuration(500);
upAnimation.setFillAfter(true);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
// TODO Auto-generated method stub
switch(ev.getAction()){
case MotionEvent.ACTION_DOWN:
//获取按下时y轴的值
downY = (int) ev.getY();
break;
case MotionEvent.ACTION_MOVE:
//获取移动时y轴的位置
int moveY=(int) ev.getY();
//判断移动的距离
int diff=moveY-downY;
//diff>0 确认是向下拉 firstVisibleItemPosition==0 确认第一个显示的是位置0
if(diff>0&&firstVisibleItemPosition==0&&headerViewCurrentState!=REFRESHING){
//获取移动后headerview的paddingtop
int paddingtop=-headerViewHeight+diff;
//判断现headerview的状态和headerview完全显示并要改变状态
if(headerViewCurrentState==PULL_REFRESH&&paddingtop>0){
//进入释放刷新状态
headerViewCurrentState=RELEASE_REFRESH;
//更新headerview
refreshTopLayout();
}else if(paddingtop<0&&headerViewCurrentState==RELEASE_REFRESH){
//进入下拉刷新状态
headerViewCurrentState=PULL_REFRESH;
refreshTopLayout();
}
//移动时headerview显示
headerView.setPadding(0, paddingtop, 0, 0);
return true;
}
break;
case MotionEvent.ACTION_UP:
//松开时-----判断是那种状态下松开的
if(headerViewCurrentState==PULL_REFRESH){
//下拉刷新状态下松开--------将头布局隐藏
headerView.setPadding(0, -headerViewHeight, 0, 0);
}else if(headerViewCurrentState==RELEASE_REFRESH){
//正在更新状态下------------
headerViewCurrentState=REFRESHING;
refreshTopLayout();
headerView.setPadding(0, 0, 0, 0);
}
break;
}
return super.onTouchEvent(ev);
}
private void refreshTopLayout() {
// TODO Auto-generated method stub
switch(headerViewCurrentState){
case PULL_REFRESH:
//
iv_picture.setAnimation(upAnimation);
tv_title.setText("下拉刷新");
break;
case RELEASE_REFRESH:
//转变成松开刷新状态下做的动作
iv_picture.startAnimation(downAnimation);
tv_title.setText("松开刷新");
break;
case REFRESHING:
//转变成正在更新状态下做的动作
iv_picture.setVisibility(View.INVISIBLE);
iv_picture.clearAnimation();
pb.setVisibility(View.VISIBLE);
tv_title.setText("释放刷新");
break;
}
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// TODO Auto-generated method stub
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
firstVisibleItemPosition = firstVisibleItem;
}
四:全部代码:
public class RefreshedListView extends ListView implements OnScrollListener {
private View headerView;
private int downY;
private int headerViewHeight;
private OnRefreshListener listener;
private final int PULL_REFRESH=0;
private final int RELEASE_REFRESH=1;
private final int REFRESHING=2;
private int headerViewCurrentState=PULL_REFRESH;
private ImageView iv_picture;
private ProgressBar pb;
private TextView tv_title;
private TextView tv_refreshtime;
private int firstVisibleItemPosition;
private RotateAnimation downAnimation;
private RotateAnimation upAnimation;
private View footerView;
private int footerViewHeight;
private int lastVisibleItemPosition;
private boolean isScrollBottom=false;
private boolean isLoadMore=false;
public RefreshedListView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
initHeader();
//设置滚动监听器
this.setOnScrollListener(this);
initFooter();
}
private void initFooter() {
footerView = View.inflate(getContext(), R.layout.footlayout, null);
footerView.measure(0, 0);
footerViewHeight = footerView.getMeasuredHeight();
footerView.setPadding(0, -footerViewHeight, 0, 0);
this.addFooterView(footerView);
}
private void initHeader() {
//创建headerview
headerView = View.inflate(getContext(), R.layout.headerlayout, null);
//获取控件
iv_picture = (ImageView) headerView.findViewById(R.id.iv_picture);
pb = (ProgressBar) headerView.findViewById(R.id.pb_progressbar);
tv_title = (TextView) headerView.findViewById(R.id.tv_title);
tv_refreshtime = (TextView) headerView.findViewById(R.id.tv_refreshtime);
tv_refreshtime.setText(ChangeSimpleDateFormat());
//让框架帮我们去测量头布局的宽和高
headerView.measure(0, 0);
headerViewHeight = headerView.getMeasuredHeight();
//设置位置
headerView.setPadding(0, -headerViewHeight, 0, 0);
this.addHeaderView(headerView);
initAnimation();
}
/**
* 旋转动画
*/
private void initAnimation() {
downAnimation = new RotateAnimation(0, -180, Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
downAnimation.setDuration(500);
downAnimation.setFillAfter(true);
upAnimation = new RotateAnimation(-180, -360, Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
upAnimation.setDuration(500);
upAnimation.setFillAfter(true);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
// TODO Auto-generated method stub
switch(ev.getAction()){
case MotionEvent.ACTION_DOWN:
//获取按下时y轴的值
downY = (int) ev.getY();
break;
case MotionEvent.ACTION_MOVE:
//获取移动时y轴的位置
int moveY=(int) ev.getY();
//判断移动的距离
int diff=moveY-downY;
//diff>0 确认是向下拉 firstVisibleItemPosition==0 确认第一个显示的是位置0
if(diff>0&&firstVisibleItemPosition==0&&headerViewCurrentState!=REFRESHING){
//获取移动后headerview的paddingtop
int paddingtop=-headerViewHeight+diff;
//判断现headerview的状态和headerview完全显示并要改变状态
if(headerViewCurrentState==PULL_REFRESH&&paddingtop>0){
//进入释放刷新状态
headerViewCurrentState=RELEASE_REFRESH;
//更新headerview
refreshTopLayout();
}else if(paddingtop<0&&headerViewCurrentState==RELEASE_REFRESH){
//进入下拉刷新状态
headerViewCurrentState=PULL_REFRESH;
refreshTopLayout();
}
//移动时headerview显示
headerView.setPadding(0, paddingtop, 0, 0);
return true;
}
break;
case MotionEvent.ACTION_UP:
//松开时-----判断是那种状态下松开的
if(headerViewCurrentState==PULL_REFRESH){
//下拉刷新状态下松开--------将头布局隐藏
headerView.setPadding(0, -headerViewHeight, 0, 0);
}else if(headerViewCurrentState==RELEASE_REFRESH){
//正在更新状态下------------
headerViewCurrentState=REFRESHING;
refreshTopLayout();
headerView.setPadding(0, 0, 0, 0);
if(listener!=null){
listener.onDownPullRefresh();
}
}
break;
}
return super.onTouchEvent(ev);
}
private void refreshTopLayout() {
// TODO Auto-generated method stub
switch(headerViewCurrentState){
case PULL_REFRESH:
//
iv_picture.setAnimation(upAnimation);
tv_title.setText("下拉刷新");
break;
case RELEASE_REFRESH:
//转变成松开刷新状态下做的动作
iv_picture.startAnimation(downAnimation);
tv_title.setText("释放刷新");
break;
case REFRESHING:
//转变成正在更新状态下做的动作
iv_picture.setVisibility(View.INVISIBLE);
iv_picture.clearAnimation();
pb.setVisibility(View.VISIBLE);
tv_title.setText("正在刷新");
break;
}
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// TODO Auto-generated method stub
if(scrollState==SCROLL_STATE_IDLE||scrollState==SCROLL_STATE_FLING){
if(isScrollBottom&&!isLoadMore){
isLoadMore = true;
footerView.setPadding(0, 0, 0, 0);
setSelection(getCount());
if(listener!=null){
listener.onLoadMore();
}
}
}
}
public void hideFooterView(){
footerView.setPadding(0, -footerViewHeight, 0, 0);
isLoadMore=false;
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
firstVisibleItemPosition = firstVisibleItem;
lastVisibleItemPosition = getLastVisiblePosition();
if(lastVisibleItemPosition==getCount()-1){
isScrollBottom = true;
}else
{
isScrollBottom=false;
}
}
public void setOnRefreshListener(OnRefreshListener listener){
this.listener=listener;
}
public void hideheaderView(){
this.setPadding(0, -headerViewHeight, 0, 0);
headerViewCurrentState=PULL_REFRESH;
iv_picture.setVisibility(View.VISIBLE);
pb.setVisibility(View.INVISIBLE);
tv_title.setText("下拉刷新");
tv_refreshtime.setText(ChangeSimpleDateFormat());
}
public String ChangeSimpleDateFormat(){
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return sdf.format(new Date());
}