目标:当一个ListView在上下滑动时(scroll up / scroll down),当List中的内容比较多时,会分批load进其中的内容。这在各类型App中很常见。我们现在就是做一个动态加载列表内容功能。
特点: 与平时的到了页底再load data不同,假如每次翻页为20条数据,我做的是当ListView滚动停下来时,离页底还有15条数据时就准备load data。也就是说在正常翻页速度下,用户是看不到load data的状态的(为了调试,要设置长一点sleep time以便观察)。
以下是部分关键代码,e.g.
listView.setOnScrollListener(new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
switch (scrollState) {
case OnScrollListener.SCROLL_STATE_IDLE:
int firstVisiblePosition = view.getFirstVisiblePosition();
if (sideData.size() < getDataCount()) { // current accumulated items count < total items count
canLoad = true;
} else {
canLoad = false;
}
if (firstVisiblePosition >= currentPage.get() * pageSize - 15) { // 离页底还有15条数据时就准备load data
int maxPage = getDataCount() / pageSize;
if (currentPage.get() + 1 <= maxPage && canLoad) {
/* 每次翻页前添加页脚 */
listView.addFooterView(footer);
listView.setAdapter(adapter);
/* 创建子线程,执行翻页 */
new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
List<String> sideDataByPage = getData(currentPage.get() + 1);
mHandler.sendMessage(mHandler.obtainMessage(1, sideDataByPage)); //add new items
}
}).start();
} else if (canLoad) {
List<String> sideDataByPage = getData(currentPage.get() + 1);
mHandler.sendMessage(mHandler.obtainMessage(2, sideDataByPage)); //add last items
}
}
break;
case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
break;
case OnScrollListener.SCROLL_STATE_FLING:
break;
default:
break;
}
}
private Handler mHandler = new Handler() {
@SuppressWarnings("unchecked")
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
/* 页脚显示完就删掉 */
if (listView.getFooterViewsCount() > 0)
listView.removeFooterView(footer);
sideData.addAll((List<String>) msg.obj);
adapter.notifyDataSetChanged();
currentPage.getAndIncrement();
break;
case 2:
sideData.addAll((List<String>) msg.obj);
adapter.notifyDataSetChanged();
currentPage.getAndIncrement();
break;
default:
break;
}
}
};
XML
- side.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@android:color/background_dark"
android:orientation="vertical" >
<ListView
android:id="@+id/side_list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"
>
</ListView>
</LinearLayout>
- side_items.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@android:color/background_dark"
android:orientation="vertical" >
<TextView
android:id="@+id/side_text_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:textSize="18sp"
android:textColor="@android:color/white"
android:lineSpacingExtra="3dp"
android:lineSpacingMultiplier="1.5"
android:layout_weight="2"
>
</TextView>
</LinearLayout>
- side_footer.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@android:color/background_dark"
android:orientation="horizontal" >
<ProgressBar
style="?android:attr/process"
android:layout_width="18dp"
android:layout_height="wrap_content" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="正在加载....."
android:textSize="18sp"
android:textColor="@android:color/white"
android:lineSpacingExtra="3dp"
android:lineSpacingMultiplier="1.5"
/>
</LinearLayout>
public List<String> getData(int currentPage) {
List<String> sideDataByPage = new ArrayList<String>();
int maxPosition = currentPage * pageSize;
if (maxPosition > getDataCount()) {
maxPosition = getDataCount();
}
for (int position = (currentPage - 1) * pageSize; position < maxPosition; position++) {
sideDataByPage.add(mStrings[position].substring(0, (mStrings[position].length() < 12)?mStrings[position].length():12)); // 防止字符过长换行
}
return sideDataByPage;
}
private String[] mStrings = {"test", "test1", ...}
public int getDataCount() {
// total items count
return mStrings.length;
}
public class Side {
private View sideView;
private ListView listView;
private View footer;
final private int pageSize = 20;
private List<String> sideData = new ArrayList<String>();
private BaseAdapter adapter;
private boolean canLoad = true;
private AtomicInteger currentPage = new AtomicInteger(1);
private SlidingViewGroup slidingViewGroup;
public Side(final Activity activity, final Context context, final SlidingViewGroup slidingViewGroup) {
setSlidingViewGroup(slidingViewGroup);
sideView = LayoutInflater.from(context).inflate(R.layout.side, null);
footer = LayoutInflater.from(context).inflate(R.layout.side_footer, null);
sideData.addAll(getData(1));
adapter = new ArrayAdapter<String>(context, R.layout.side_items,
R.id.side_text_view, sideData);
listView = (ListView) this.sideView.findViewById(R.id.side_list);
listView.setAdapter(adapter);
...
效果图