博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
指令汇B新闻客户端开发(三) 下拉刷新
阅读量:6160 次
发布时间:2019-06-21

本文共 5405 字,大约阅读时间需要 18 分钟。

现在我们继续这个新闻客户端的开发,今天分享的是下拉刷新的实现,我们都知道下拉刷新是一个应用很常见也很实用的功能。我这个应用是通过拉ListView来实现刷新的,先看一张刷新的原理图

从图中可知,手指移动的距离就是dy。

刷新分为三种状态:下拉刷新、正在刷新、松开刷新;

定义这三种状态为:

private static final int STATE_PULL_REFRESH = 0;// 下拉刷新

private static final int STATE_RELEASE_REFRESH = 1;// 松开刷新
private static final int STATE_REFRESHING = 2;// 正在刷新

接下来开始写我们的代码了

初始化头布局:

private void initHeaderView() {		mHeaderView = View.inflate(getContext(), R.layout.refresh_header, null);		this.addHeaderView(mHeaderView);		tvTitle = (TextView) mHeaderView.findViewById(R.id.tv_title);		tvTime = (TextView) mHeaderView.findViewById(R.id.tv_time);		ivArrow = (ImageView) mHeaderView.findViewById(R.id.iv_arr);		pbProgress = (ProgressBar) mHeaderView.findViewById(R.id.pb_progress);		mHeaderView.measure(0, 0);		mHeaderViewHeight = mHeaderView.getMeasuredHeight();		mHeaderView.setPadding(0, -mHeaderViewHeight, 0, 0);// 隐藏头布局		initArrowAnim();		tvTime.setText("最后刷新时间:" + getCurrentTime());	}
初始化脚布局

* 初始化脚布局	 */	private void initFooterView() {		mFooterView = View.inflate(getContext(),				R.layout.refresh_listview_footer, null);		this.addFooterView(mFooterView);		mFooterView.measure(0, 0);		mFooterViewHeight = mFooterView.getMeasuredHeight();		mFooterView.setPadding(0, -mFooterViewHeight, 0, 0);// 隐藏		this.setOnScrollListener(this);	}
初始化箭头的动画:

/**	 * 初始化箭头动画	 */	private void initArrowAnim() {		// 箭头向上动画		animUp = new RotateAnimation(0, -180, Animation.RELATIVE_TO_SELF, 0.5f,				Animation.RELATIVE_TO_SELF, 0.5f);		animUp.setDuration(200); 		animUp.setFillAfter(true);		// 箭头向下动画		animDown = new RotateAnimation(-180, 0, Animation.RELATIVE_TO_SELF,				0.5f, Animation.RELATIVE_TO_SELF, 0.5f);		animDown.setDuration(200);		animDown.setFillAfter(true);	}

接下来是实现触摸的方法及偏移量的计算:

@Override	public boolean onTouchEvent(MotionEvent ev) {		switch (ev.getAction()) {		case MotionEvent.ACTION_DOWN:			startY = (int) ev.getRawY();			break;		case MotionEvent.ACTION_MOVE:			if (startY == -1) {// 确保startY有效				startY = (int) ev.getRawY();			}			if (mCurrrentState == STATE_REFRESHING) {// 正在刷新时不做处理				break;			}			int endY = (int) ev.getRawY();			int dy = endY - startY;// 移动偏移量			if (dy > 0 && getFirstVisiblePosition() == 0) {// 只有下拉并且当前是第一个item,才允许下拉				int padding = dy - mHeaderViewHeight;// 计算padding				mHeaderView.setPadding(0, padding, 0, 0);// 设置当前padding				if (padding > 0 && mCurrrentState != STATE_RELEASE_REFRESH) {// 状态改为松开刷新					mCurrrentState = STATE_RELEASE_REFRESH;					refreshState();				} else if (padding < 0 && mCurrrentState != STATE_PULL_REFRESH) {// 改为下拉刷新状态					mCurrrentState = STATE_PULL_REFRESH;					refreshState();				}				return true;			}			break;		case MotionEvent.ACTION_UP:			startY = -1;// 重置			if (mCurrrentState == STATE_RELEASE_REFRESH) {				mCurrrentState = STATE_REFRESHING;// 正在刷新				mHeaderView.setPadding(0, 0, 0, 0);// 显示				refreshState();			} else if (mCurrrentState == STATE_PULL_REFRESH) {				mHeaderView.setPadding(0, -mHeaderViewHeight, 0, 0);// 隐藏			}			break;		default:			break;		}		return super.onTouchEvent(ev);	}
刷新下拉控件的布局:

private void refreshState() {		switch (mCurrrentState) {		case STATE_PULL_REFRESH:			tvTitle.setText("下拉刷新");			ivArrow.setVisibility(View.VISIBLE);			pbProgress.setVisibility(View.INVISIBLE);			ivArrow.startAnimation(animDown);			break;		case STATE_RELEASE_REFRESH:			tvTitle.setText("松开刷新");			ivArrow.setVisibility(View.VISIBLE);			pbProgress.setVisibility(View.INVISIBLE);			ivArrow.startAnimation(animUp);			break;		case STATE_REFRESHING:			tvTitle.setText("正在刷新...");			ivArrow.clearAnimation();// 必须先清除动画,才能隐藏			ivArrow.setVisibility(View.INVISIBLE);			pbProgress.setVisibility(View.VISIBLE);			if (mListener != null) {				mListener.onRefresh();			}			break;		default:			break;		}	}
刷新完成之后我们需要收起这个下拉刷新的按钮,额,好吧,总的来说比较复杂了:

/*	 * 收起下拉刷新的控件	 */	public void onRefreshComplete(boolean success) {		if (isLoadingMore) {// 正在加载更多...			mFooterView.setPadding(0, -mFooterViewHeight, 0, 0);// 隐藏脚布局			isLoadingMore = false;		} else {			mCurrrentState = STATE_PULL_REFRESH;			tvTitle.setText("下拉刷新");			ivArrow.setVisibility(View.VISIBLE);			pbProgress.setVisibility(View.INVISIBLE);			mHeaderView.setPadding(0, -mHeaderViewHeight, 0, 0);// 隐藏			if (success) {				tvTime.setText("最后刷新时间:" + getCurrentTime());			}		}	}
我们还可以看到上面有一个实时的时间,获取当前系统时间:

/**	 * 获取当前时间	 */	public String getCurrentTime() {		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");		return format.format(new Date());	}	private boolean isLoadingMore;	@Override	public void onScrollStateChanged(AbsListView view, int scrollState) {		if (scrollState == SCROLL_STATE_IDLE				|| scrollState == SCROLL_STATE_FLING) {			if (getLastVisiblePosition() == getCount() - 1 && !isLoadingMore) {// 滑动到最后			//	System.out.println("到底了.....");				mFooterView.setPadding(0, 0, 0, 0);// 显示				setSelection(getCount() - 1);// 改变listview显示位置				isLoadingMore = true;				if (mListener != null) {					mListener.onLoadMore();				}			}		}	}
在新闻详情页里面要设置一下下拉刷新监听:

// 设置下拉刷新监听		lvList.setOnRefreshListener(new OnRefreshListener() {			@Override			public void onRefresh() {				getDataFromServer();			}			@Override			public void onLoadMore() {				if (mMoreUrl != null) {					getMoreDataFromServer();				} else {					Toast.makeText(mActivity, "最后一页了", Toast.LENGTH_SHORT)							.show();					lvList.onRefreshComplete(false);// 收起加载更多的布局				}			}		});
这里刷新功能基本上实现了,这里只写出了关键代码。

转载于:https://www.cnblogs.com/xiaowangba/p/6314913.html

你可能感兴趣的文章
【Xcode】编辑与调试
查看>>
用tar和split将文件分包压缩
查看>>
[BTS] Could not find stored procedure 'mp_sap_check_tid'
查看>>
PLSQL DBMS_DDL.ALTER_COMPILE
查看>>
Activity生命周期
查看>>
高仿UC浏览器弹出菜单效果
查看>>
Ubuntu忘记密码,进不了系统的解决方法
查看>>
[原创]白盒测试技术思维导图
查看>>
<<Information Store and Management>> 读书笔记 之八
查看>>
Windows 8 开发之设置合约
查看>>
闲说HeartBeat心跳包和TCP协议的KeepAlive机制
查看>>
MoSQL
查看>>
Hibernate多对一外键单向关联(Annotation配置)
查看>>
《CLR via C#》读书笔记 之 方法
查看>>
设计模式:组合模式(Composite Pattern)
查看>>
ContentValues 和HashTable区别
查看>>
LogicalDOC 6.6.2 发布,文档管理系统
查看>>
给PowerShell脚本传递参数
查看>>
实战2——Hadoop的日志分析
查看>>
利用FIFO进行文件拷贝一例
查看>>