展会信息港展会大全

Android开发中动态加载ListView实现
来源:互联网   发布日期:2015-11-26 11:26:50   浏览:1705次  

导读:如今动态加载成为app 必有的功能,本质上我并不需要一次性加载所有东西,尤其是联网加载时候,前几天看到一篇博文讲国外一个开源解决方案,感觉他的做法并不完美于是发表自己的一些拙见!android listview 动态 ...

如今动态加载成为app 必有的功能,本质上我并不需要一次性加载所有东西,尤其是联网加载时候,前几天看到一篇博文讲国外一个开源解决方案,感觉他的做法并不完美于是发表自己的一些拙见!

android listview 动态加载

首先讲原理:

ListView 可以设置一个滚动监听器

android.widget.AbsListView.setOnScrollListener(OnScrollListener l)

有个方法

public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)

这里面有三个参数:

firstVisibleItem: 第一个可见Item在所有Item中的位置(即屏幕上显示的第一行,在你的数据数组中的位置)

visibleItemCount: 可见Item个数(屏幕内可以显示多少行)

totalItemCount: 总共有多少行数据

通过这个3个参数容易想到,如果firstVisibleItem +visibleItemCount >=totalItemCount 不就表明 列表已经滑到了底部么?这个时候就是我们加载数据的时机了!

然后我们需要在列表底部增加一个 item 显示:点击加载更多 或者 正在加载中请稍后 或者 没有更多数据了

这个我们要用到

ListView.addFooterView(View v)

添加了 footView ,footView 就成了列表最后一行,也就说相对于你的总数据增加了一行,所有这里有一点要注意的地方:

调用这个方法必须在 ListView.SetAdapter() 之前,否则将会影响 Cursor 类适配器

知道了原理就很简单了,下面奉上我封装的 LoaderListView

/**

* 下拉自动加载的 Listview

*

* @author Yichou

* @创建日期 2013-3-19 16:01:10

*

* 2013-6-30

*/

public class LoaderListView extends ListView implements

OnScrollListener,

OnItemClickListener,

OnClickListener {

public interface LoadNotifyer {

public void load();

}

public interface OnScrollStateChangedListener {

public void onScrollStateChanged(int oldState, int newState);

}

private LinearLayout footViewLoading, footViewRetry, footViewNomore;

private LoadNotifyer loadNotifyer;

private int scrollState;

private OnScrollStateChangedListener onScrollStateChangedListener;

public LoaderListView(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

init(context);

}

public LoaderListView(Context context, AttributeSet attrs) {

super(context, attrs);

init(context);

}

public LoaderListView(Context context) {

super(context);

init(context);

}

@Override

public void onClick(View v) {

if(v.getId() == 0x1001){ //重新加载

setFootviewType(FOOTVIEW_TYPE.LOADING);

if(loadNotifyer != null)

loadNotifyer.load();

}else if (v.getId() == 0x1002) {

setSelection(0);

}

}

private void init(Context context) {

footViewLoading = new LinearLayout(context);

footViewLoading.setOrientation(LinearLayout.HORIZONTAL);

footViewLoading.setGravity(Gravity.CENTER);

ProgressBar bar = new ProgressBar(context);

TextView textView = new TextView(context);

textView.setText("加载中...");

footViewLoading.addView(bar, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));

footViewLoading.addView(textView, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));

footViewRetry = new LinearLayout(context);

footViewRetry.setOrientation(LinearLayout.HORIZONTAL);

footViewRetry.setGravity(Gravity.CENTER);

textView = new TextView(context);

textView.setId(0x1001);

textView.setGravity(Gravity.CENTER);

textView.setText("网络不给力,请重试 o(︶︿︶)o");

textView.setOnClickListener(this);

footViewRetry.addView(textView, new LayoutParams(LayoutParams.WRAP_CONTENT, getFixPx(50)));

footViewNomore = new LinearLayout(context);

footViewNomore.setOrientation(LinearLayout.HORIZONTAL);

footViewNomore.setGravity(Gravity.CENTER);

footViewNomore.setId(0x1002);

textView = new TextView(context);

textView.setText("返回顶部 ");

textView.setGravity(Gravity.CENTER);

footViewNomore.setClickable(true);

footViewNomore.setOnClickListener(this);

footViewNomore.addView(textView, new LayoutParams(LayoutParams.WRAP_CONTENT, getFixPx(50)));

setFootviewType(FOOTVIEW_TYPE.LOADING);

setOnScrollListener(this);

scrollState = SCROLL_STATE_IDLE;

super.setOnItemClickListener(this);

}

public enum FOOTVIEW_TYPE {

/** 加载中 */

LOADING,

/** 没有更多了,返回顶部 */

NOMOR,

/** 加载失败重试 */

RETRY,

/**无*/

NONE

}

private View curFootView;

public void setFootviewType(FOOTVIEW_TYPE type) {

if(curFootView != null && curFootView.getTag() == type)

return;

if(curFootView != null)

removeFooterView(curFootView);

switch (type) {

case LOADING:

curFootView = footViewLoading;

break;

case NOMOR:

curFootView = footViewNomore;

break;

case RETRY:

curFootView = footViewRetry;

break;

case NONE:

return;

}

addFooterView(curFootView);

curFootView.setTag(type);

}

private View curHeadView;

public void setHeadView(View v) {

if(curHeadView!=null)

return;

curHeadView=v;

addHeaderView(v);

}

@Override

public void onScrollStateChanged(AbsListView view, int scrollState) {

if (scrollState != this.scrollState) {

if(onScrollStateChangedListener != null){

onScrollStateChangedListener.onScrollStateChanged(this.scrollState, scrollState);

}

this.scrollState = scrollState;

}

}

protected int firstVisibleItem, visibleItemCount, totalItemCount;

@Override

public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {

if(totalItemCount < 2 ) //footview 也算

return;

// System.out.println("first=" + firstVisibleItem + ",visible=" + visibleItemCount + ",total=" + totalItemCount);

if(firstVisibleItem + visibleItemCount >= totalItemCount){ //说明 footView 可见,通知加载更多

if (loadNotifyer != null && (curFootView != footViewNomore)) {

loadNotifyer.load();

}

}

this.firstVisibleItem = firstVisibleItem;

this.visibleItemCount = visibleItemCount;

this.totalItemCount = totalItemCount;

}

public int getFirstVisibleItem() {

return firstVisibleItem;

}

public int getVisibleItemCount() {

return visibleItemCount;

}

public int getScrollState() {

return scrollState;

}

public void setLoadNotifyer(LoadNotifyer loadNotifyer) {

this.loadNotifyer = loadNotifyer;

}

public void setOnScrollStateChangedListener(OnScrollStateChangedListener onScrollStateChangedListener) {

this.onScrollStateChangedListener = onScrollStateChangedListener;

}

public int getFixPx(int dp){

float scale=getContext().getResources().getDisplayMetrics().density;

return (int)(scale*dp+0.5);

}

private OnItemClickListener listener;

@Override

public void setOnItemClickListener(OnItemClickListener listener) {

this.listener = listener;

// super.setOnItemClickListener(listener);

}

@Override

public void onItemClick(AdapterView<?> parent, View view, int position,

long id) {

if(listener==null)return;

if(curHeadView != null){

if(position==0)return;

listener.onItemClick(parent, view, position-1, id);

}else{

listener.onItemClick(parent, view, position, id);

}

}

}

使用很方便,只需调用

LoaderListView.setLoadNotifyer(LoadNotifyer loadNotifyer)

然后每次滑到底部需要加载更多数据的时候,就会回调

LoadNotifyer.load()

然后你在 load() 方法里加载下一页数据,加载完毕调用

Adapter.notifyDataSetChanged()

列表就展示新数据了!

此外我这里面还封装了一个神奇的功能是设置 FootView 状态:

这里有四种状态:

public enum FOOTVIEW_TYPE {

/** 加载中 */

LOADING,

/** 没有更多了,返回顶部 */

NOMOR,

/** 加载失败重试 */

RETRY,

/**无*/

NONE

}

在加载下一页失败的时候,调用

listView.setFootviewType(FOOTVIEW_TYPE.RETRY)

列表底部显示改为,加载失败,点击重试,用户点击之后,会再次回调你的 load() 方法

同理

当你没有更多数据的时候调用

listView.setFootviewType(FOOTVIEW_TYPE.NOMOR)

列表底部显示改为 回到顶部 用户点击后自动跳到第一行!

赞助本站

人工智能实验室

相关热词: 动态加载 ListView Android

AiLab云推荐
推荐内容
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港