Добавлен вспомагательный класс для создания бесконечных списков

This commit is contained in:
Victor 2013-08-29 16:30:36 +03:00
parent 3a419f0c3b
commit 131e65fbe4
2 changed files with 138 additions and 53 deletions

View File

@ -2,72 +2,34 @@ package com.annimon.client.fragments;
import android.app.ListFragment;
import android.os.Bundle;
import android.widget.AbsListView;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import com.annimon.client.utils.MoreListHelper;
import java.util.ArrayList;
public class MailFragment extends ListFragment {
private int itemsPerPage = 10;
private boolean loadingMore = false;
private ArrayList<String> items;
private ArrayAdapter<String> adapter;
private MoreListHelper<String> moreListHelper;
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
items = new ArrayList<String>();
adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, items);
// FooterView для показа информации о подгрузке данных
TextView footerView = new TextView(getActivity());
footerView.setText("Loading...");
getListView().addFooterView(footerView);
setListAdapter(adapter);
getListView().setOnScrollListener(new AbsListView.OnScrollListener(){
moreListHelper = new MoreListHelper<String>(getActivity(), getListView()) {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
int lastInScreen = firstVisibleItem + visibleItemCount;
if((lastInScreen == totalItemCount) && !(loadingMore)){
Thread thread = new Thread(loadMoreListItems);
thread.start();
public void onLoadItems(ArrayList<String> items, int itemsPerPage) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {}
for (int i = 0; i < itemsPerPage; i++) {
items.add(String.valueOf(System.currentTimeMillis()));
}
}
});
Thread thread = new Thread(loadMoreListItems);
thread.start();
};
moreListHelper.setItemsPerPage(15);
moreListHelper.createAdapter(android.R.layout.simple_list_item_1);
setListAdapter(moreListHelper.getAdapter());
moreListHelper.loadItems();
}
private Runnable loadMoreListItems = new Runnable() {
@Override
public void run() {
loadingMore = true;
items = new ArrayList<String>();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {}
for (int i = 0; i < itemsPerPage; i++) {
items.add(String.valueOf(System.currentTimeMillis()));
}
getActivity().runOnUiThread(returnRes);
}
};
private Runnable returnRes = new Runnable() {
@Override
public void run() {
if(items != null && items.size() > 0){
adapter.addAll(items);
}
adapter.notifyDataSetChanged();
loadingMore = false;
}
};
}

View File

@ -0,0 +1,123 @@
package com.annimon.client.utils;
import android.app.Activity;
import android.view.View;
import android.widget.AbsListView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import java.util.ArrayList;
/**
* Вспомагательный класс для создания подгружаемых списков.
*
* @author aNNiMON
*/
public abstract class MoreListHelper<T> {
private int itemsPerPage;
private Activity activity;
private ArrayList<T> items;
private ArrayAdapter<T> adapter;
private boolean loadingMore;
public MoreListHelper(Activity activity, ListView listView) {
this(activity, listView, null);
}
public MoreListHelper(Activity activity, ListView listView, View footerView) {
itemsPerPage = 10;
this.activity = activity;
if (footerView == null) {
// Создаём footer по умочанию.
footerView = new TextView(activity);
((TextView) footerView).setText("Loading...");
}
loadingMore = false;
items = new ArrayList<T>();
listView.addFooterView(footerView);
listView.setOnScrollListener(scrollListener);
}
/**
* Создаёт новый адаптер из ресурса разметки.
* @param layoutResource ресурс разметки
*/
public void createAdapter(int layoutResource) {
adapter = new ArrayAdapter<T>(activity, layoutResource, items);
}
public ArrayAdapter<T> getAdapter() {
return adapter;
}
public void setAdapter(ArrayAdapter<T> adapter) {
this.adapter = adapter;
}
/**
* Задаёт количество элементов на страницу.
* Используется при загрузке новых элементов для ограничения загружаемых данных.
* @param value количество элементов
*/
public void setItemsPerPage(int value) {
itemsPerPage = value;
}
public void loadItems() {
Thread thread = new Thread(loadMoreListItemsRunnable);
thread.start();
}
private AbsListView.OnScrollListener scrollListener = new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
int lastInScreen = firstVisibleItem + visibleItemCount;
if ( (lastInScreen == totalItemCount) && !loadingMore ){
loadItems();
}
}
};
/**
* Метод загрузки новых элементов списка.
* Выполняется в отдельном треде.
* @param items список для заполнения
* @param itemsPerPage количество элементов на страницу (по умолчанию 10)
*/
public abstract void onLoadItems(ArrayList<T> items, int itemsPerPage);
private Runnable loadMoreListItemsRunnable = new Runnable() {
@Override
public void run() {
loadingMore = true;
items = new ArrayList<T>();
// Загружаем данные.
onLoadItems(items, itemsPerPage);
// Обновляем список и адаптер.
activity.runOnUiThread(updateAdapterRunnable);
}
};
private Runnable updateAdapterRunnable = new Runnable() {
@Override
public void run() {
if ( (items != null) && (items.size() > 0) ){
adapter.addAll(items);
}
adapter.notifyDataSetChanged();
loadingMore = false;
}
};
}