Android的listview添加头和脚的另一种方式

给listview和recyclerview添加header和footer,我们一般常用的方式,有如下几种:
xml文件:


1.自定义listview和recyclerview.添加头和尾
2.使用第三方框架PullToRefresh进行添加头和尾
3.使用谷歌最新推出的控件SwipeRefreshLayout,下面我们就来讲解一下怎么使用谷歌最新的特性进行添加头和尾
该控件有一个缺点:自带功能中没有添加叫布局加载更多的方法.
上图:


只需要添加下拉加载更多的话,直接使用原生的控件即可:
上代码:
privateListViewlv;
privateArrayListlist=newArrayList<>();
privateListviewAdaptermAdapter;
privateSwipeRefreshLayoutswipe;
@Override
protected voidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv= (ListView) findViewById(R.id.lv_listview);
swipe= (SwipeRefreshLayout) findViewById(R.id.swipe);
init();
//设置下拉刷新的颜色
swipe.setProgressBackgroundColorSchemeResource(android.R.color.holo_red_light);
//下拉时触发SwipeRefreshLayout的下拉动画,动画完毕之后就会回调这个方法
swipe.setOnRefreshListener(newSwipeRefreshLayout.OnRefreshListener() {
@Override
public voidonRefresh() {
//开始刷新,设置当前为刷新状态
//swipeRefreshLayout.setRefreshing(true);
//这里是主线程
//一些比较耗时的操作,比如联网获取数据,需要放到子线程去执行
//TODO获取数据
finalRandom random =newRandom();
newHandler().postDelayed(newRunnable() {
@Override
public voidrun() {
list.add(0,"我是刷新天才"+random.nextInt(100) +"号");
mAdapter.notifyDataSetChanged();
Toast.makeText(MainActivity.this,"刷新了一条数据", Toast.LENGTH_SHORT).show();
//加载完数据设置为不刷新状态,将下拉进度收起来
swipe.setRefreshing(false);
}
},2000);
}
});
}
/**
*@authorhy
@time2016/10/1 17:57
/
private voidinit() {
addData();
if(list!=null) {
if(mAdapter==null) {
mAdapter=newListviewAdapter(this,list);
lv.setAdapter(mAdapter);
}else{
mAdapter.notifyDataSetChanged();
}
}
}
/

*@authorhy
@time2016/10/1 17:57
/
public voidaddData() {
for(inti =1; i <=100; i++) {
list.add("我是天才"+ i +"号");
}
}
xml布局文件:
就是一个swipeRefreshLayout里面包裹一个listview即可.
添加footer,上啦加载更多,自定义该控件.
/

*作者:hy on 2016/10/2 00:02
邮箱: simoncqhy@163.com
/
public classSwipeRefreshViewextendsSwipeRefreshLayout {
privateViewmFooterView;
//滑动的最小距离
private intmSlop;
//获取listview
privateListViewmListView;
privateOnLoadListenermOnLoadListener;
//正在加载状态
private booleanisLoading;
publicSwipeRefreshView(Context context) {
this(context,null);
}
publicSwipeRefreshView(Context context, AttributeSet attrs) {
super(context, attrs);
mFooterView= View.inflate(context, R.layout.view_footer,null);
//设置滑动的最小距离,大于该距离才能滑动。
mSlop= ViewConfiguration.get(context).getScaledTouchSlop();
}
@Override
protected voidonLayout(booleanchanged,intleft,inttop,intright,intbottom) {
super.onLayout(changed, left, top, right, bottom);
if(mListView==null) {
//判断容器有多少个子孩子
if(getChildCount()>0) {
//判断第一个孩子是不是ListView
if(getChildAt(0)instanceofListView) {
//创建ListView对象
mListView= (ListView) getChildAt(0);
//设置ListView的滑动监听
setListViewOnScroll();
}
}
}
}
//设置listview的滑动监听
private voidsetListViewOnScroll() {
mListView.setOnScrollListener(newAbsListView.OnScrollListener() {
@Override
public voidonScrollStateChanged(AbsListView view,intscrollState) {
//移动过程中判断时候能下拉加载更多
if(canLoadMore()) {
//加载数据
loadData();
}
}
@Override
public voidonScroll(AbsListView view,intfirstVisibleItem,intvisibleItemCount,inttotalItemCount) {
}
});
}
/

*分发事件的处理
*@paramev
@return
/
private floatmDownY,mUpY;
@Override
public booleandispatchTouchEvent(MotionEvent ev) {
switch(ev.getAction()) {
caseMotionEvent.ACTION_DOWN:
//移动的起点
mDownY= ev.getY();
break;
caseMotionEvent.ACTION_MOVE:
//移动过程中判断时候能下拉加载更多
if(canLoadMore()) {
//加载数据
loadData();
}
break;
caseMotionEvent.ACTION_UP:
//移动的终点
mUpY= getY();
break;
}
return super.dispatchTouchEvent(ev);
}
/

*判断是否能够加载更多
@return
/
private booleancanLoadMore() {
// 1.是上拉状态
booleancondition1 = (mDownY-mUpY) >=mSlop;
if(condition1) {
System.out.println("是上拉状态");
}
// 2.当前页面可见的item是最后一个条目
booleancondition2 =false;
if(mListView!=null&&mListView.getAdapter() !=null) {
condition2 =mListView.getLastVisiblePosition() == (mListView.getAdapter().getCount() -1);
}
if(condition2) {
System.out.println("是最后一个条目");
}
// 3.正在加载状态
booleancondition3 = !isLoading;
if(condition3) {
System.out.println("不是正在加载状态");
}
returncondition1 && condition2 && condition3;
}
/

处理加载数据的逻辑
/
private voidloadData() {
System.out.println("加载数据...");
if(mOnLoadListener!=null) {
//设置加载状态,让布局显示出来
setLoading(true);
mOnLoadListener.onLoad();
}
}
/

*设置加载状态,是否加载传入boolean值进行判断

@paramloading
/
public voidsetLoading(booleanloading) {
//修改当前的状态
isLoading= loading;
if(isLoading) {
//显示布局
mListView.addFooterView(mFooterView);
}else{
//隐藏布局
mListView.removeFooterView(mFooterView);
//重置滑动的坐标
mDownY=0;
mUpY=0;
}
}
/

上拉加载的接口回调
/
public interfaceOnLoadListener {
voidonLoad();
}
public voidsetOnLoadListener(OnLoadListener listener) {
this.mOnLoadListener= listener;
}
}
使用:
/

*作者:hy on 2016/10/2 00:16
邮箱: simoncqhy@163.com
/
public classCustomActivityextendsAppCompatActivity {
privateListmList;
private intmCount;
privateStringAdaptermAdapter;
@Override
protected voidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_custom);
finalSwipeRefreshView swipeRefreshView = (SwipeRefreshView) findViewById(R.id.srl);
finalListView listView = (ListView) findViewById(R.id.lv);
//设置适配器数据
mList=newArrayList<>();
for(inti =0; i <30; i++) {
mList.add("我是天才"+ i +"号");
mCount++;
}
mAdapter=newStringAdapter();
listView.setAdapter(mAdapter);
//不能在onCreate中设置,这个表示当前是刷新状态,如果一进来就是刷新状态,SwipeRefreshLayout会屏蔽掉下拉事件
//swipeRefreshLayout.setRefreshing(true);
//设置颜色属性的时候一定要注意是引用了资源文件还是直接设置16进制的颜色,因为都是int值容易搞混
//设置下拉进度的背景颜色,默认就是白色的
swipeRefreshView.setProgressBackgroundColorSchemeResource(android.R.color.white);
//设置下拉进度的主题颜色
swipeRefreshView.setColorSchemeResources(R.color.colorAccent, R.color.colorPrimary, R.color.colorPrimaryDark);
//下拉时触发SwipeRefreshLayout的下拉动画,动画完毕之后就会回调这个方法
swipeRefreshView.setOnRefreshListener(newSwipeRefreshLayout.OnRefreshListener() {
@Override
public voidonRefresh() {
//开始刷新,设置当前为刷新状态
//swipeRefreshLayout.setRefreshing(true);
//这里是主线程
//一些比较耗时的操作,比如联网获取数据,需要放到子线程去执行
//TODO获取数据
finalRandom random =newRandom();
newHandler().postDelayed(newRunnable() {
@Override
public voidrun() {
mList.add(0,"我是下拉天才"+random.nextInt(100) +"号");
mAdapter.notifyDataSetChanged();
Toast.makeText(CustomActivity.this,"刷新了一条数据", Toast.LENGTH_SHORT).show();
//加载完数据设置为不刷新状态,将下拉进度收起来
swipeRefreshView.setRefreshing(false);
}
},2000);
}
});
//设置下拉加载更多
swipeRefreshView.setOnLoadListener(newSwipeRefreshView.OnLoadListener() {
@Override
public voidonLoad() {
newHandler().postDelayed(newRunnable() {
@Override
public voidrun() {
//添加数据
for(inti =30; i <35; i++) {
mList.add("我是加载更多天才"+ i+"号");
//这里要放在里面刷新,放在外面会导致刷新的进度条卡住
mAdapter.notifyDataSetChanged();
}
Toast.makeText(CustomActivity.this,"加载了"+5+"条数据", Toast.LENGTH_SHORT).show();
//加载完数据设置为不加载状态,将加载进度收起来
swipeRefreshView.setLoading(false);
}
},2000);
}
});
}
/

*适配器
*/
private classStringAdapterextendsBaseAdapter {
@Override
public intgetCount() {
returnmList.size();
}
@Override
publicObject getItem(intposition) {
returnmList.get(position);
}
@Override
public longgetItemId(intposition) {
returnposition;
}
@Override
publicView getView(intposition, View convertView, ViewGroup parent) {
if(convertView ==null) {
convertView = View.inflate(CustomActivity.this, android.R.layout.simple_list_item_1,null);
}
TextView tv = (TextView) convertView;
tv.setGravity(Gravity.CENTER);
tv.setPadding(0,20,0,20);
tv.setText(mList.get(position));
returnconvertView;
}
}
}
源码下载地址
百度云盘:
http://pan.baidu.com/s/1eRU3mpG

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,194评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,058评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,780评论 0 346
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,388评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,430评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,764评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,907评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,679评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,122评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,459评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,605评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,270评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,867评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,734评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,961评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,297评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,472评论 2 348

推荐阅读更多精彩内容