最近在做一个新闻类的项目,把自己写的一点东西记录下来,希望自己能够慢慢的成长,也希望自己帮到他人,哈哈哈···
自定义下拉刷新和加载更多,首先要初始化一个头和一个尾,加到(ListView)中
//尾,简称上拉刷新的布局吧
private void initFooterView(Context context) {
footView=View.inflate(context,R.layout.refresh_foot_view,null);
pb_status_bottom= (ProgressBar) footView.findViewById(R.id.pb_status_bottom);
tv_status_bottom= (TextView) footView.findViewById(R.id.tv_status_bottom);
footView.measure(0,0);
footViewHeight=footView.getMeasuredHeight();
footView.setPadding(0,-footViewHeight,0,0);
//ListView自带的方法
addFooterView(footView);
setOnScrollListener(new MyOnScrollListener());
}
//头,就是下拉刷新的一个布局
private void initHeaderView(Context context) {
headerView = (LinearLayout) View.inflate(context, R.layout.refresh_header, null);
ll_pull_down_refresh = headerView.findViewById(R.id.ll_pull_down_refresh);
iv_refresh_image = (ImageView) headerView.findViewById(R.id.iv_refresh_image);
tv_status = (TextView) headerView.findViewById(R.id.tv_status);
tv_time = (TextView) headerView.findViewById(R.id.tv_time);
pb_status = (ProgressBar) headerView.findViewById(R.id.pb_status);
//测量
ll_pull_down_refresh.measure(0, 0);
//控件的高
viewHeight = ll_pull_down_refresh.getMeasuredHeight();
/**
* 默认隐藏下拉刷新控件
*/
ll_pull_down_refresh.setPadding(0, -viewHeight, 0, 0);
}
//重写一个接口,在需要调用的时候,在实例化的时候通过自定义的控件调用
//一个是下拉刷新对应头,一个是加载更多对应尾
/**
* 监听事件的刷新
*/
public interface OnRefreshListener{
/**
当下拉刷新的时候回调这个方法
*/
void onPullDownRefresh();
/**
当加载更多的时候回调这个方法
*/
void onLoadMore();
}
//如果顶部有轮播图加上,把这个布局加入到headerView中,没有的话,就不要加入了
/**
* 添加顶部轮播图
* @param topNewsView
*/
public void addTopNewsView(View topNewsView) {
if (topNewsView!=null) {
this.topNewsView = topNewsView;
headerView.addView(topNewsView);
}
}
/**
* 得到当前Android系统的时间
*
* @return
*/
private String getSystemTime() {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return format.format(new Date());
}
//通过触摸事件来判断
/**
* 判断是否完全显示顶部轮播图
* @return
*/
private boolean isDisplayTopNews() {
if (topNewsView!=null) {
//1.得到listview在屏幕上的坐标
int[] location = new int[2];
if (listviewScreenY == -1) {
getLocationOnScreen(location);
listviewScreenY = location[1];
}
//2.得到顶部轮播图在屏幕上的坐标
topNewsView.getLocationOnScreen(location);
int topNewsViewOnScreenY = location[1];
if (listviewScreenY <= topNewsViewOnScreenY) {
return true;
} else {
return false;
}
}else {
return true;
}
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()){
case MotionEvent.ACTION_DOWN:
//记录起始坐标
startY=ev.getY();
break;
case MotionEvent.ACTION_MOVE:
if (startY==-1){
startY=ev.getY();
}
//判断头部轮播图是否完全显示,只有完全显示才会下拉刷新
boolean isDisplayTopNews=isDisplayTopNews();
if (!isDisplayTopNews){
//加载更多
break;
}else {
}
if (currentStatus==REFRESHING){
break;
}
//2.来到新的坐标
float endY=ev.getY();
//记录滑动的坐标
float deltaY=endY-startY;
if (deltaY>0){
int paddingTop= (int) (-viewHeight+deltaY);
if (paddingTop < 0 && currentStatus != PULL_DOWN_REFRESH) {
//下拉刷新状态
currentStatus = PULL_DOWN_REFRESH;
//更新状态
refreshViewState();
} else if (paddingTop > 0 && currentStatus != RELEASE_REFRESH) {
//手松刷新状态
currentStatus = RELEASE_REFRESH;
//更新状态
refreshViewState();
}
ll_pull_down_refresh.setPadding(0, paddingTop, 0, 0);
}
break;
case MotionEvent.ACTION_UP:
startY=-1;
if (currentStatus == PULL_DOWN_REFRESH) {//下拉刷新
// View.setPadding(0,-控件高,0,0);
//完全隐藏
ll_pull_down_refresh.setPadding(0, -viewHeight, 0, 0);
} else if (currentStatus == RELEASE_REFRESH) {
//设置状态为正在刷新
currentStatus = REFRESHING;
refreshViewState();
ll_pull_down_refresh.setPadding(0, 0, 0, 0);
//回调接口
if (mOnRefreshListener != null) {
mOnRefreshListener.onPullDownRefresh();
}
}
break;
}
return super.onTouchEvent(ev);
}
private void refreshViewState() {
switch (currentStatus){
case PULL_DOWN_REFRESH://下拉刷新状态
iv_refresh_image.startAnimation(downAnimation);
tv_status.setText("下拉刷新....");
break;
case RELEASE_REFRESH://手松刷新状态
iv_refresh_image.startAnimation(upAnimation);
tv_status.setText("手松刷新....");
break;
case REFRESHING://正在刷新状态
tv_status.setText("正在刷新....");
pb_status.setVisibility(VISIBLE);
iv_refresh_image.clearAnimation();
iv_refresh_image.setVisibility(GONE);
break;
}
}
/**
* 当联网成功和失败的时候回调该方法
* 用户刷新状态的还原
* 控件进行调用这个方法
* @param sucess
*/
public void onRefreshFinish(boolean sucess) {
if (!isLoadMore) {//不加载更多
tv_status.setText("下拉刷新...");
currentStatus = PULL_DOWN_REFRESH;
pb_status.setVisibility(GONE);
iv_refresh_image.setVisibility(VISIBLE);
//隐藏下拉刷新控件
ll_pull_down_refresh.setPadding(0, -viewHeight, 0, 0);
if (sucess) {
//设置最新更新时间
tv_time.setText("上次更新时间:" + getSystemTime());
}
}else {
isLoadMore=false;
//隐藏加载更多布局
footView.setPadding(0,-footViewHeight,0,0);
}
}
<?xml version="1.0" encoding="utf-8"?>
<!--尾部刷新布局-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:padding="8dp"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ProgressBar
android:id="@+id/pb_status_bottom"
android:layout_gravity="center" android:indeterminateDrawable="@drawable/progress_bar_selector"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:layout_marginLeft="10dp"
android:text="加载更多"
android:textColor="#ff0000"
android:textSize="18sp"
android:id="@+id/tv_status_bottom"
android:gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--头部刷新-->
<!--下拉刷新控件-->
<LinearLayout
android:id="@+id/ll_pull_down_refresh"
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_gravity="center">
<ProgressBar
android:id="@+id/pb_status"
android:layout_gravity="center"
android:indeterminateDrawable="@drawable/progress_bar_selector"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</FrameLayout>
<LinearLayout
android:layout_gravity="center_vertical"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:text="下拉刷新"
android:textColor="#ff0000"
android:textSize="18sp"
android:id="@+id/tv_status"
android:gravity="center_horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:text="上次更新时间:2017-8-4"
android:textColor="#55000000"
android:textSize="18sp"
android:id="@+id/tv_time"
android:gravity="center_horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
布局如上
具体怎么用
private RefreshListView lv_news_content;
private boolean isLoadMore=false;
@Override
public View initView() {
View view = View.inflate(context, R.layout.tab_detail_pager, null);
lv_news_content = (RefreshListView) view.findViewById(R.id.lv_news_content);
View topNewsView = View.inflate(context, R.layout.topnews, null);
view_pager = (HorizontalScrollViewPager) topNewsView.findViewById(R.id.view_pager);
tv_tab_detile_title = (TextView) topNewsView.findViewById(R.id.tv_tab_detile_title);
ll_point_group = (LinearLayout) topNewsView.findViewById(R.id.ll_point_group);
//而且要把顶部轮播图部分,以子布局的形式加入到listview中
// lv_news_content.addHeaderView(topNewsView);
lv_news_content.addTopNewsView(topNewsView);
//设置listview的下拉刷新监听事件
lv_news_content.setOnRefreshListenenr(new MyOnRefreshListener());
//设置listview的点击监听
lv_news_content.setOnItemClickListener(new MyItemClickListener());
return view;
}
class MyOnRefreshListener implements RefreshListView.OnRefreshListener {
@Override
public void onPullDownRefresh() {
Toast.makeText(context, "你在下拉刷新", Toast.LENGTH_SHORT).show();
getDataFromNet();
}
@Override
public void onLoadMore() {
if (TextUtils.isEmpty(moreUrl)){
Toast.makeText(context, "没有更多数据", Toast.LENGTH_SHORT).show();
lv_news_content.onRefreshFinish(false);
}else {
getMoreDataFromNet();
}
}
}
到此就完了,可能说的不是很清楚