ListView实现下拉刷新加载更多的实例代码(直接拿来用)

ListView Api bixu 好好看看

mNewsAdapter.notifyDataSetChanged();//刷新ListView

自定义的RefreashListView

package com.itguang.dell_pc.myapplication.view;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.AbsListView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.itguang.dell_pc.myapplication.R;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 作者: 小光哥 on 2016/7/7.
* 邮箱: 1445037803@qq.com
* 修订历史:
* 描述:
*         ┏┓   ┏┓
*        ┏┛┻━━━┛┻┓━━━━┻┓
*        ┃       ┃
*        ┃   ━   ┃
*        ┃ >   < ┃
*        ┃       ┃
*        ┃... ⌒ ... ┃
*        ┃       ┃
*        ┗━┓   ┏━┛
*          ┃   ┃ Code is far away from bug with the animal protecting
*          ┃ 史 ┃ 神兽保佑,代码无bug
*          ┃ 诗 ┃
*          ┃ 之 ┃
*          ┃ 宠 ┃
*          ┃   ┃
*          ┃   ┗━━━┓
*          ┃BUG天敌   ┣┓┣┓┣┓┣┓┣┓
*          ┃       ┏┛
*          ┗┓┓┏━┳┓┏┛
*           ┃┫┫ ┃┫┫
*           ┗┻┛ ┗┻┛
*/
public class RefreshListView extends ListView implements AbsListView.OnScrollListener {
private static final int STATE_PULL_REFRESH = 0;// 下拉刷新
private static final int STATE_RELEASE_REFRESH = 1;// 松开刷新
private static final int STATE_REFRESHING = 2;// 正在刷新
private int mCurrrentState = STATE_PULL_REFRESH;// 当前状态
private View mHeaderView;
private TextView tvTitle;
private TextView tvTime;
private ProgressBar pbProgress;
private ImageView ivArrow;
private RotateAnimation animUp;
private RotateAnimation animDown;
private int startY = -1;// 滑动起点的y坐标
private int endY;
private int measuredHeight;
private int mFooterViewHeight;
private View footerView;
public RefreshListView(Context context) {
super(context);
initHeaderView();
initFooterView();
}
public RefreshListView(Context context, AttributeSet attrs) {
super(context, attrs);
initHeaderView();
initFooterView();
}
public RefreshListView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initHeaderView();
initFooterView();
}
/**
* 初始化头布局
*/
private void initHeaderView() {
mHeaderView = View.inflate(getContext(), R.layout.refeeash_header, null);
this.addHeaderView(mHeaderView);
tvTitle = (TextView) mHeaderView.findViewById(R.id.tv_title);
tvTime = (TextView) mHeaderView.findViewById(R.id.tv_time);
pbProgress = (ProgressBar) mHeaderView.findViewById(R.id.pb_progress);
ivArrow = (ImageView) mHeaderView.findViewById(R.id.iv_arr);
mHeaderView.measure(0, 0);//先测量再拿到它的高度
measuredHeight = mHeaderView.getMeasuredHeight();
mHeaderView.setPadding(0, -measuredHeight, 0, 0);
initArrowAnim();
tvTime.setText("最后刷新时间:" + getCurrentTime());
}
/**
* 初始化脚布局
*/
public void initFooterView() {
footerView = View.inflate(getContext(), R.layout.refreash_listview_footer, null);
this.addFooterView(footerView);
footerView.measure(0, 0);
mFooterViewHeight = footerView.getMeasuredHeight();
footerView.setPadding(0, -mFooterViewHeight, 0, 0);//默认隐藏脚布局
this.setOnScrollListener(this);
}
private boolean isLoadingMOre;
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (scrollState == SCROLL_STATE_FLING || scrollState == SCROLL_STATE_IDLE) {
if (getLastVisiblePosition() == getCount() - 1 && !isLoadingMOre) {//滑倒最后
System.out.println("到底了......");
footerView.setPadding(0, 0, 0, 0);
setSelection(getCount() - 1);//改变ListView的显示位置
isLoadingMOre = true;
if (mListener != null) {
mListener.onLoadMore();
}
}
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}
@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) {//有时候不会响应 MotionEvent.ACTION_DOWN 事件,这是要重新获取startY坐标
startY = (int) ev.getRawY();
}
//当正在刷新的时候,跳出循环,不再执行下面逻辑
if (mCurrrentState == STATE_RELEASE_REFRESH) {
break;
}
endY = (int) ev.getRawY();
int dy = endY - startY;//计算手指滑动距离
if (dy > 0 && getFirstVisiblePosition() == 0) {// 只有下拉并且当前是第一个item,才允许下拉
int padding = dy - measuredHeight;//计算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, -measuredHeight, 0, 0);// 隐藏
}
break;
default:
break;
}
return super.onTouchEvent(ev);
}
private String getCurrentTime() {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String currentTime = format.format(new Date());
return currentTime;
}
private void initArrowAnim() {
//初始化箭头动画
animUp = new RotateAnimation(0, -180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
animUp.setDuration(500);
animUp.setFillAfter(true);//保持状态
//箭头向下动画
animDown = new RotateAnimation(-180, 0, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
animDown.setDuration(500);
animDown.setFillAfter(true);
}
/**
* 刷新下拉控件的布局
*/
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.onRefreash();
}
break;
default:
break;
}
}
OnRefreashListener mListener;
public void setOnRefreashListener(OnRefreashListener listener) {
mListener = listener;
}
public interface OnRefreashListener {
void onRefreash();
void onLoadMore();
}
/**
* 收起下拉刷新的控件
*/
public void onRefreashComplete() {
if (isLoadingMOre) {
footerView.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, -measuredHeight, 0, 0);//隐藏
}
}
public void noFooterView() {
footerView.setPadding(0, mFooterViewHeight, 0, 0);//隐藏脚布局
}
}

代码中引用RefreashListView

package com.itguang.dell_pc.myapplication.base;
import android.app.Activity;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.google.gson.Gson;
import com.itguang.dell_pc.myapplication.R;
import com.itguang.dell_pc.myapplication.domain.NewsData;
import com.itguang.dell_pc.myapplication.domain.TabData;
import com.itguang.dell_pc.myapplication.globe.GlobeContents;
import com.itguang.dell_pc.myapplication.view.RefreshListView;
import com.lidroid.xutils.BitmapUtils;
import com.lidroid.xutils.HttpUtils;
import com.lidroid.xutils.ViewUtils;
import com.lidroid.xutils.exception.HttpException;
import com.lidroid.xutils.http.ResponseInfo;
import com.lidroid.xutils.http.callback.RequestCallBack;
import com.lidroid.xutils.http.client.HttpRequest;
import com.lidroid.xutils.view.annotation.ViewInject;
import com.viewpagerindicator.CirclePageIndicator;
import java.util.ArrayList;
/**
* 作者: 小光哥 on 2016/4/22.
* 邮箱: 1445037803@qq.com
* 修订历史:
* 描述:
*         ┏┓   ┏┓
*        ┏┛┻━━━┛┻┓━━━━┻┓
*        ┃       ┃
*        ┃   ━   ┃
*        ┃ >   < ┃
*        ┃       ┃
*        ┃... ⌒ ... ┃
*        ┃       ┃
*        ┗━┓   ┏━┛
*          ┃   ┃ Code is far away from bug with the animal protecting
*          ┃ 史 ┃ 神兽保佑,代码无bug
*          ┃ 诗 ┃
*          ┃ 之 ┃
*          ┃ 宠 ┃
*          ┃   ┃
*          ┃   ┗━━━┓
*          ┃BUG天敌   ┣┓┣┓┣┓┣┓┣┓
*          ┃       ┏┛
*          ┗┓┓┏━┳┓┏┛
*           ┃┫┫ ┃┫┫
*           ┗┻┛ ┗┻┛
*/
/**
* 也签详情页
*/
public class TabDetailPager extends BaseMenuDetailPager implements ViewPager.OnPageChangeListener {
/**
* @param activity
* @param newsTabData
*/
NewsData.NewsTabData mTabdata;
private String mUrl;
private TabData mTabDetailData;
@ViewInject(R.id.vp_news)
private ViewPager mViewPager;
@ViewInject(R.id.lv_newslist)
private RefreshListView newsListView;//新闻列表
@ViewInject(R.id.tv_title)
private TextView tvTitle;//新闻标题
@ViewInject(R.id.indicator)
private CirclePageIndicator indicator;//头条新闻指示器
private ArrayList<TabData.TopNewsData> mTopNewsList;//新闻数据集合
private int[] images;
private ArrayList<TabData.TabNewsData> mNewsList;//新闻数据集合
private String mMoreUrl;
private NewsAdapter mNewsAdapter;
public TabDetailPager(Activity activity, NewsData.NewsTabData newsTabData) {
super(activity);
mTabdata = newsTabData;
mUrl = GlobeContents.SERVER_URL + mTabdata.url;
}
@Override
public View initViews() {
images = new int[]{R.drawable.topnews1, R.drawable.topnews21, R.drawable.topnews31, R.drawable.topimage};
View view = View.inflate(mActivity, R.layout.tab_detail_pager, null);
View headerView = View.inflate(mActivity, R.layout.list_header_topnews, null);//加载头布局
// TextView tvTitle = (TextView) view.findViewById(R.id.tv_title);
//事件注入
ViewUtils.inject(this, view);
ViewUtils.inject(this, headerView);
mViewPager.addOnPageChangeListener(this);
//将肥头条新闻以头布局形式加载到listView中
newsListView.addHeaderView(headerView);
//设置下拉刷新监听
newsListView.setOnRefreashListener(new RefreshListView.OnRefreashListener() {
@Override
public void onRefreash() {
getDataFromServer();
}
@Override
public void onLoadMore() {
if (mMoreUrl != null) {
getMoreDataFromServer();
} else {
Toast.makeText(mActivity, "没有更多数据了", Toast.LENGTH_SHORT).show();
newsListView.onRefreashComplete();
// newsListView.noFooterView();
}
}
});
return view;
}
@Override
public void initData() {
getDataFromServer();//这是一个异步的,
}
private void getDataFromServer() {
HttpUtils utils = new HttpUtils();
utils.send(HttpRequest.HttpMethod.GET, mUrl, new RequestCallBack<String>() {
@Override
public void onSuccess(ResponseInfo<String> responseInfo) {
String result = (String) responseInfo.result;
// System.out.println("页签详情页返回结果:+++++++++++++++++++" + result);
praseData(result, false);
newsListView.onRefreashComplete();
}
@Override
public void onFailure(HttpException e, String s) {
Toast.makeText(mActivity, "获取Tabdetaildata失败!", Toast.LENGTH_SHORT).show();
// error.printStackTrace();
}
});
}
/**
* 加载下一页数据
*/
private void getMoreDataFromServer() {
HttpUtils utils = new HttpUtils();
utils.send(HttpRequest.HttpMethod.GET, mMoreUrl, new RequestCallBack<String>() {
@Override
public void onSuccess(ResponseInfo<String> responseInfo) {
String result = (String) responseInfo.result;
// System.out.println("页签详情页返回结果:+++++++++++++++++++" + result);
praseData(result, true);
newsListView.onRefreashComplete();
}
@Override
public void onFailure(HttpException e, String s) {
Toast.makeText(mActivity, "获取Tabdetaildata失败!", Toast.LENGTH_SHORT).show();
// error.printStackTrace();
}
});
}
/**
* 把json字符串解析成为json对象
*
* @param result 要解析的的json字符串
*/
private void praseData(String result, boolean isLoadMore) {
Gson gson = new Gson();
mTabDetailData = gson.fromJson(result, TabData.class);//返回TabData对象
System.out.println("页签详情页:+++++++++++++++++++++" + mTabdata);
//处理更多页面的逻辑
final String more = mTabDetailData.data.more;
if (!TextUtils.isEmpty(more)) {
mMoreUrl = GlobeContents.SERVER_URL + more;
} else {
mMoreUrl = null;
}
if (!isLoadMore) {
mTopNewsList = mTabDetailData.data.topnews;
mNewsList = mTabDetailData.data.news;
if (mTopNewsList != null) {
mViewPager.setAdapter(new TopNewsAdapter());
indicator.setOnPageChangeListener(this);
indicator.setViewPager(mViewPager);//在设置完适配器后,在设置指示器
indicator.setSnap(true);//设置快照显示
indicator.onPageSelected(0);//indicator会自作聪明,离开时会记录当前位置
tvTitle.setText(mTopNewsList.get(0).title);
}
mNewsAdapter = new NewsAdapter();
//填充新闻列表
if (mNewsList != null) {
newsListView.setAdapter(mNewsAdapter);
}
} else {//如果是加载下一页,需要将数据追加给原来的集合
ArrayList<TabData.TabNewsData> news = mTabDetailData.data.news;
mNewsList.addAll(news);
mNewsAdapter.notifyDataSetChanged();//刷新ListView
}
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {//更新头条新闻标题
TabData.TopNewsData topNewsData = mTopNewsList.get(position);
tvTitle.setText(topNewsData.title);
}
@Override
public void onPageScrollStateChanged(int state) {
}
/**
* ListView适配器
*/
class NewsAdapter extends BaseAdapter {
private final BitmapUtils utils;
NewsAdapter() {
utils = new BitmapUtils(mActivity);
utils.configDefaultLoadingImage(R.drawable.pic_item_list_default);
}
@Override
public int getCount() {
return mNewsList.size();
}
@Override
public Object getItem(int position) {
return mNewsList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = View.inflate(mActivity, R.layout.list_news_item, null);
holder = new ViewHolder();
holder.ivPic = (ImageView) convertView.findViewById(R.id.iv_pic);
holder.tvTitle = (TextView) convertView.findViewById(R.id.tv_title);
holder.tvDate = (TextView) convertView.findViewById(R.id.tv_date);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
TabData.TabNewsData item = (TabData.TabNewsData) getItem(position);
holder.tvTitle.setText(item.title);
holder.tvDate.setText(item.pubdate);
utils.display(holder.ivPic, item.listimage);
return convertView;
}
}
static class ViewHolder {
public TextView tvTitle;
public TextView tvDate;
public ImageView ivPic;
}
/**
* Viewpager适配器
*/
class TopNewsAdapter extends PagerAdapter {
private BitmapUtils bitmapUtils;
TopNewsAdapter() {
bitmapUtils = new BitmapUtils(mActivity);
bitmapUtils.configDefaultLoadingImage(R.drawable.topnews_item_default);//设置默认图片
}
@Override
public int getCount() {
return mTabDetailData.data.topnews.size();
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
ImageView imageView = new ImageView(mActivity);
imageView.setImageResource(images[position]);
imageView.setScaleType(ImageView.ScaleType.FIT_XY);//基于控件大小填充图片
// TabData.TopNewsData topNewsData = mTopNewsList.get(position);
// bitmapUtils.display(imageView,mTabDetailData.data.topnews.get(position).url);
container.addView(imageView);
return imageView;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
}
}

以上所述是小编给大家介绍的ListView实现下拉刷新加载更多的实例代码(直接拿来用)的全部叙述,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的,在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • Android ListView实现上拉加载下拉刷新和滑动删除功能

    最近项目需要用到可以滑动删除并且带有上拉加载下拉刷新的Listview,查阅了一些资料,大多都是在SwipeMenuListView的基础上去添加头部和底部View,来扩展上拉加载和下拉刷新的功能,不过需要手动的去绘制UI及处理一些动画效果.用起来也不是特别方便.刚好项目中用到PulltorefreshLibrary库,就尝试着扩展了一个PullToRefreshSwipeMenuListView类来实现需求.先看一下效果: 实现步骤 一.组合Pulltorefresh与SwipeMenuLis

  • Android仿XListView支持下拉刷新和上划加载更多的自定义RecyclerView

    首先给大家展示下效果图,感觉还不错,请继续往下阅读: 下拉刷新:        上划加载        在项目更新的过程中,遇到了一个将XListView换成recyclerView的需求,而且更换完之后大体效果不能变,但是对于下拉刷新这样的效果,谷歌给出的解决方案是把RecyclerView放在一个SwipeRefreshLayout中,但是这样其实是拉下一个小圆形控件实现的,和XListView的header效果不同.在网上找了很多的别人代码,都没有实现我想要的效果,于是自己动手写了一个.

  • Android ListView实现上拉加载更多和下拉刷新功能

    本文实例为大家介绍了Android ListView下拉刷新功能的实现方法和功能,供大家参考,具体内容如下 1.ListView优化方式 界面缓存:ViewHolder+convertView 分页加载:上拉刷新 图片缓存 快速滑动ListView禁止刷新 2.效果 3.上拉加载更多原理及实现 当我们手指滑动到listview最后位置的时候,我们触发加载数据的方法.这触发之前我们需要做一些工作,包括: 如何判断滑动到最后? 如何避免重复加载数据? 加载之后如何刷新界面? 1).界面实现AbsLi

  • Android ListView实现下拉加载功能

    本文实例为大家分享了ListView下拉加载展示的具体代码,供大家参考,具体内容如下 1.MyListView.Java public class MyListView extends ListView implements OnScrollListener { private final static int RELEASE_To_REFRESH = 0;// 下拉过程的状态值 private final static int PULL_To_REFRESH = 1; // 从下拉返回到不刷新

  • Android开发ListView中下拉刷新上拉加载及带列的横向滚动实现方法

    ListView 控件可使用四种不同视图显示项目.通过此控件,可将项目组成带有或不带有列标头的列,并显示伴随的图标和文本. 可使用 ListView 控件将称作 ListItem 对象的列表条目组织成下列四种不同的视图之一:1.大(标准)图标2.小图标3.列表4.报表 View 属性决定在列表中控件使用何种视图显示项目. 还可用 LabelWrap 属性控制列表中与项目关联的标签是否可换行显示.另外,还可管理列表中项目的排序方法和选定项目的外观. 相信有很人做的项目估计都用的到这个.就是List

  • Android自定义listview布局实现上拉加载下拉刷新功能

    listview实现上拉加载以及下拉刷新的方式有很多.下面是我写的一种自定义的布局,复用性也比较的强.首先就是继承的listview的自定义view.   AutoListView.Java: package com.example.mic.testdemo.view; import android.annotation.TargetApi; import android.content.Context; import android.os.Build; import android.os.Bu

  • Android ListView下拉刷新上拉自动加载更多DEMO示例

    代码下载地址已经更新.因为代码很久没更新,已经很落伍了,建议大家使用RecyclerView实现. 参考项目: https://github.com/bingoogolapple/BGARefreshLayout-Android https://github.com/baoyongzhang/android-PullRefreshLayout 下拉刷新,Android中非常普遍的功能.为了方便便重写的ListView来实现下拉刷新,同时添加了上拉自动加载更多的功能.设计最初是参考开源中国的And

  • Android程序开发之Listview下拉刷新上拉(滑动分页)加载更多

    最近做的类似于微博的项目中,有个Android功能要使用到listview的向下拉刷新来刷新最新消息,向上拉刷新(滑动分页)来加载更多. 新浪微博就是使用这种方式的典型. 当用户从网络上读取微博的时候,如果一下子全部加载用户未读的微博这将耗费比较长的时间,造成不好的用户体验,同时一屏的内容也不足以显示如此多的内容.这时候,我们就需要用到另一个功能,那就是listview的分页了,其实这个分页可以做成客户端的分页,也可以做成服务器端的分页(点击加载时,从服务器对应的加载第N页就好了!!!).通过分

  • Android XListView下拉刷新和上拉加载更多

    市面上有好多的类比ListView刷新数据的开源框架,如:v4包自带的SwipeRefreshLayout ,以及集ListView.GridView甚至WebView于一身的Pulltorefresh等等.前述的两个开源框架目前使用也算频繁.有兴趣的读者可以自行搜索,当然有时间一定回来对所有的使用方式做一个汇总和比较.今天介绍的这款框架,专门针对ListView做下拉刷新与上拉加载的,如果单单是ListView就显得更加简单方便易于理解. 1.首先引入xListView_lib库到自己的Dem

  • Android实现上拉加载更多以及下拉刷新功能(ListView)

    首先为大家介绍Andorid5.0原生下拉刷新简单实现. 先上效果图: 相对于上一个19.1.0版本中的横条效果好看了很多.使用起来也很简单. <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/container" and

随机推荐